install_framework_base/
cache.rs

1// Copyright 2021 Yuri6037
2
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
21use std::string::String;
22use std::collections::HashMap;
23use std::marker::PhantomData; //Because rust is a peace of shit
24use 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}