1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
use serde_derive::Deserialize;
use std::path::{Path, PathBuf};
use toml::de;
type Error = std::io::Error;
use std::io::ErrorKind;
use crate::backends::{Backend, ClangBackend, ClangCBackend, PythonBackend};
#[derive(Debug, Deserialize)]
pub struct Conf {
#[serde(skip)]
path: Option<PathBuf>,
#[serde(default)]
python: PythonBackend,
#[serde(default)]
clang: ClangBackend,
#[serde(default)]
clang_c: ClangCBackend,
}
impl Conf {
pub fn get_backend(&self, fname: &Path) -> Option<Box<&dyn Backend>> {
let ext = fname.extension().and_then(|ext| ext.to_str()).unwrap_or("");
match ext {
"py" => Some(Box::new(&self.python)),
"cc" | "cpp" | "cxx" => Some(Box::new(&self.clang)),
"c" => Some(Box::new(&self.clang_c)),
_ => None,
}
}
}
pub fn get_conf() -> Result<Conf, Error> {
let mut current = std::env::current_dir()?;
let path = loop {
let candidate = current.join(".evr");
if candidate.exists() {
break candidate;
}
if !current.pop() {
return Err(Error::new(ErrorKind::NotFound, "Not a evr subtree"));
}
};
let raw_buf = std::fs::read_to_string(path.as_path())?;
let buf_result: Result<Conf, de::Error> = de::from_str(&raw_buf);
buf_result
.map(|mut buf| {
buf.path = Some(path.clone());
buf
})
.map_err(|err| Error::new(ErrorKind::InvalidData, err))
}
|