install_framework_base/
cache.rs1use std::string::String;
22use std::collections::HashMap;
23use std::marker::PhantomData; use std::path::PathBuf;
25use std::path::Path;
26use std::ffi::OsString;
27#[cfg(not(feature="keep-cache"))]
28use tempfile::tempdir;
29#[cfg(not(feature="keep-cache"))]
30use tempfile::TempDir;
31
32#[cfg(feature="keep-cache")]
33struct TempDir
34{
35 path: PathBuf
36}
37
38#[cfg(feature="keep-cache")]
39impl TempDir
40{
41 pub fn path(&self) -> &Path
42 {
43 return &self.path;
44 }
45}
46
47#[cfg(feature="keep-cache")]
48fn tempdir() -> std::io::Result<TempDir>
49{
50 let path = Path::new(".").join("cache");
51 if path.exists()
52 {
53 std::fs::remove_dir_all(&path)?;
54 }
55 std::fs::create_dir(&path)?;
56 return Ok(TempDir
57 {
58 path: path
59 });
60}
61
62use crate::error::Error;
63
64fn gen_cache<TError: Error>() -> Result<TempDir, TError::ErrorType>
65{
66 let temp = match tempdir()
67 {
68 Ok(v) => v,
69 Err(e) => return Err(TError::io(e))
70 };
71 return Ok(temp);
72}
73
74pub struct Cache<TError: Error>
75{
76 cached: Option<TempDir>,
77 cache: HashMap<usize, OsString>,
78 uselessbrokenrust: PhantomData<TError>
79}
80
81impl <TError: Error> Cache<TError>
82{
83 pub fn new() -> Cache<TError>
84 {
85 return Cache
86 {
87 cached: None,
88 cache: HashMap::new(),
89 uselessbrokenrust: PhantomData
90 };
91 }
92
93 pub fn get_path(&mut self, path: &Path) -> Result<PathBuf, TError::ErrorType>
94 {
95 match &self.cached
96 {
97 Some(v) => return Ok(v.path().join(path)),
98 None =>
99 {
100 let dir = gen_cache::<TError>()?;
101 let res = dir.path().join(path);
102 self.cached = Some(dir);
103 return Ok(res);
104 }
105 }
106 }
107
108 pub fn insert<TVal: Into<OsString>>(&mut self, resid: usize, value: TVal)
109 {
110 self.cache.insert(resid, value.into());
111 }
112
113 pub fn get(&self, resid: usize) -> Result<&OsString, TError::ErrorType>
114 {
115 match self.cache.get(&resid)
116 {
117 None => return Err(TError::unknown_resource(resid)),
118 Some(v) => return Ok(v)
119 };
120 }
121
122 pub fn parse_string(&self, from: &str) -> Result<OsString, TError::ErrorType>
123 {
124 let mut s = OsString::new();
125 let mut resblk = false;
126 let mut tmp = String::new();
127
128 for c in from.chars()
129 {
130 let mut fuck = false;
131 if c == '%'
132 {
133 resblk = !resblk;
134 if !resblk
135 {
136 if tmp.starts_with("%res:")
137 {
138 let resid: usize = match tmp[5..tmp.len()].parse()
139 {
140 Ok(v) => v,
141 Err(e) => return Err(TError::parse_int(e))
142 };
143 if let Some(v) = self.cache.get(&resid)
144 {
145 s.push(v);
146 fuck = true;
147 }
148 else
149 {
150 return Err(TError::unknown_resource(resid))
151 }
152 }
153 else
154 {
155 s.push(&tmp);
156 }
157 tmp = String::new();
158 }
159 }
160 if resblk
161 {
162 tmp.push(c);
163 }
164 else
165 {
166 if !fuck
167 {
168 s.push(c.to_string());
169 }
170 }
171 }
172 return Ok(s);
173 }
174}