]> git.proxmox.com Git - rustc.git/blob - src/vendor/mdbook/src/book/bookconfig.rs
New upstream version 1.19.0+dfsg1
[rustc.git] / src / vendor / mdbook / src / book / bookconfig.rs
1 extern crate toml;
2
3 use std::process::exit;
4 use std::fs::File;
5 use std::io::Read;
6 use std::path::{Path, PathBuf};
7 use std::collections::BTreeMap;
8 use std::str::FromStr;
9 use serde_json;
10
11 #[derive(Debug, Clone)]
12 pub struct BookConfig {
13 root: PathBuf,
14 pub dest: PathBuf,
15 pub src: PathBuf,
16 pub theme_path: PathBuf,
17
18 pub title: String,
19 pub author: String,
20 pub description: String,
21
22 pub indent_spaces: i32,
23 multilingual: bool,
24 }
25
26 impl BookConfig {
27 pub fn new(root: &Path) -> Self {
28 BookConfig {
29 root: root.to_owned(),
30 dest: root.join("book"),
31 src: root.join("src"),
32 theme_path: root.join("theme"),
33
34 title: String::new(),
35 author: String::new(),
36 description: String::new(),
37
38 indent_spaces: 4, // indentation used for SUMMARY.md
39 multilingual: false,
40 }
41 }
42
43 pub fn read_config(&mut self, root: &Path) -> &mut Self {
44
45 debug!("[fn]: read_config");
46
47 let read_file = |path: PathBuf| -> String {
48 let mut data = String::new();
49 let mut f: File = match File::open(&path) {
50 Ok(x) => x,
51 Err(_) => {
52 error!("[*]: Failed to open {:?}", &path);
53 exit(2);
54 }
55 };
56 if f.read_to_string(&mut data).is_err() {
57 error!("[*]: Failed to read {:?}", &path);
58 exit(2);
59 }
60 data
61 };
62
63 // Read book.toml or book.json if exists
64
65 if root.join("book.toml").exists() {
66
67 debug!("[*]: Reading config");
68 let data = read_file(root.join("book.toml"));
69 self.parse_from_toml_string(&data);
70
71 } else if root.join("book.json").exists() {
72
73 debug!("[*]: Reading config");
74 let data = read_file(root.join("book.json"));
75 self.parse_from_json_string(&data);
76
77 } else {
78 debug!("[*]: No book.toml or book.json was found, using defaults.");
79 }
80
81 self
82 }
83
84 pub fn parse_from_toml_string(&mut self, data: &str) -> &mut Self {
85 let config = match toml::from_str(data) {
86 Ok(x) => {x},
87 Err(e) => {
88 error!("[*]: Toml parse errors in book.toml: {:?}", e);
89 exit(2);
90 }
91 };
92
93 self.parse_from_btreemap(&config);
94
95 self
96 }
97
98 /// Parses the string to JSON and converts it to BTreeMap<String, toml::Value>.
99 pub fn parse_from_json_string(&mut self, data: &str) -> &mut Self {
100
101 let c: serde_json::Value = match serde_json::from_str(data) {
102 Ok(x) => x,
103 Err(e) => {
104 error!("[*]: JSON parse errors in book.json: {:?}", e);
105 exit(2);
106 }
107 };
108
109 let config = json_object_to_btreemap(c.as_object().unwrap());
110 self.parse_from_btreemap(&config);
111
112 self
113 }
114
115 pub fn parse_from_btreemap(&mut self, config: &BTreeMap<String, toml::Value>) -> &mut Self {
116
117 // Title, author, description
118 if let Some(a) = config.get("title") {
119 self.title = a.to_string().replace("\"", "");
120 }
121 if let Some(a) = config.get("author") {
122 self.author = a.to_string().replace("\"", "");
123 }
124 if let Some(a) = config.get("description") {
125 self.description = a.to_string().replace("\"", "");
126 }
127
128 // Destination folder
129 if let Some(a) = config.get("dest") {
130 let mut dest = PathBuf::from(&a.to_string().replace("\"", ""));
131
132 // If path is relative make it absolute from the parent directory of src
133 if dest.is_relative() {
134 dest = self.get_root().join(&dest);
135 }
136 self.set_dest(&dest);
137 }
138
139 // Source folder
140 if let Some(a) = config.get("src") {
141 let mut src = PathBuf::from(&a.to_string().replace("\"", ""));
142 if src.is_relative() {
143 src = self.get_root().join(&src);
144 }
145 self.set_src(&src);
146 }
147
148 // Theme path folder
149 if let Some(a) = config.get("theme_path") {
150 let mut theme_path = PathBuf::from(&a.to_string().replace("\"", ""));
151 if theme_path.is_relative() {
152 theme_path = self.get_root().join(&theme_path);
153 }
154 self.set_theme_path(&theme_path);
155 }
156
157 self
158 }
159
160 pub fn get_root(&self) -> &Path {
161 &self.root
162 }
163
164 pub fn set_root(&mut self, root: &Path) -> &mut Self {
165 self.root = root.to_owned();
166 self
167 }
168
169 pub fn get_dest(&self) -> &Path {
170 &self.dest
171 }
172
173 pub fn set_dest(&mut self, dest: &Path) -> &mut Self {
174 self.dest = dest.to_owned();
175 self
176 }
177
178 pub fn get_src(&self) -> &Path {
179 &self.src
180 }
181
182 pub fn set_src(&mut self, src: &Path) -> &mut Self {
183 self.src = src.to_owned();
184 self
185 }
186
187 pub fn get_theme_path(&self) -> &Path {
188 &self.theme_path
189 }
190
191 pub fn set_theme_path(&mut self, theme_path: &Path) -> &mut Self {
192 self.theme_path = theme_path.to_owned();
193 self
194 }
195 }
196
197 pub fn json_object_to_btreemap(json: &serde_json::Map<String, serde_json::Value>) -> BTreeMap<String, toml::Value> {
198 let mut config: BTreeMap<String, toml::Value> = BTreeMap::new();
199
200 for (key, value) in json.iter() {
201 config.insert(
202 String::from_str(key).unwrap(),
203 json_value_to_toml_value(value.to_owned())
204 );
205 }
206
207 config
208 }
209
210 pub fn json_value_to_toml_value(json: serde_json::Value) -> toml::Value {
211 match json {
212 serde_json::Value::Null => toml::Value::String("".to_string()),
213 serde_json::Value::Bool(x) => toml::Value::Boolean(x),
214 serde_json::Value::Number(ref x) if x.is_i64() => toml::Value::Integer(x.as_i64().unwrap()),
215 serde_json::Value::Number(ref x) if x.is_u64() => toml::Value::Integer(x.as_i64().unwrap()),
216 serde_json::Value::Number(x) => toml::Value::Float(x.as_f64().unwrap()),
217 serde_json::Value::String(x) => toml::Value::String(x),
218 serde_json::Value::Array(x) => {
219 toml::Value::Array(x.iter().map(|v| json_value_to_toml_value(v.to_owned())).collect())
220 },
221 serde_json::Value::Object(x) => {
222 toml::Value::Table(json_object_to_btreemap(&x))
223 },
224 }
225 }