]> git.lizzy.rs Git - rust.git/blob - src/tools/jsondocck/src/cache.rs
8a6a911321c345a57c8fd0384359190d18791773
[rust.git] / src / tools / jsondocck / src / cache.rs
1 use crate::error::CkError;
2 use serde_json::Value;
3 use std::collections::HashMap;
4 use std::path::{Path, PathBuf};
5 use std::{fs, io};
6
7 #[derive(Debug)]
8 pub struct Cache {
9     root: PathBuf,
10     files: HashMap<PathBuf, String>,
11     values: HashMap<PathBuf, Value>,
12     pub variables: HashMap<String, Value>,
13     last_path: Option<PathBuf>,
14 }
15
16 impl Cache {
17     /// Create a new cache, used to read files only once and otherwise store their contents.
18     pub fn new(doc_dir: &str) -> Cache {
19         Cache {
20             root: Path::new(doc_dir).to_owned(),
21             files: HashMap::new(),
22             values: HashMap::new(),
23             variables: HashMap::new(),
24             last_path: None,
25         }
26     }
27
28     fn resolve_path(&mut self, path: &String) -> PathBuf {
29         if path != "-" {
30             let resolve = self.root.join(path);
31             self.last_path = Some(resolve.clone());
32             resolve
33         } else {
34             self.last_path.as_ref().unwrap().clone()
35         }
36     }
37
38     fn read_file(&mut self, path: PathBuf) -> Result<String, io::Error> {
39         if let Some(f) = self.files.get(&path) {
40             return Ok(f.clone());
41         }
42
43         let file = fs::read_to_string(&path)?;
44
45         self.files.insert(path, file.clone());
46
47         Ok(file)
48     }
49
50     /// Get the text from a file. If called multiple times, the file will only be read once
51     pub fn get_file(&mut self, path: &String) -> Result<String, io::Error> {
52         let path = self.resolve_path(path);
53         self.read_file(path)
54     }
55
56     /// Parse the JSON from a file. If called multiple times, the file will only be read once.
57     pub fn get_value(&mut self, path: &String) -> Result<Value, CkError> {
58         let path = self.resolve_path(path);
59
60         if let Some(v) = self.values.get(&path) {
61             return Ok(v.clone());
62         }
63
64         let content = self.read_file(path.clone())?;
65         let val = serde_json::from_str::<Value>(&content)?;
66
67         self.values.insert(path, val.clone());
68
69         Ok(val)
70     }
71 }