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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use std::convert::TryFrom;
use std::collections::HashMap;
use std::path::Path;
use std::fs::File;
use std::io::Write;
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use toml;
use super::{Arch, OS, Target, Error};
use super::parse_toml;
mod v0;
mod v1;
mod v2;
pub use self::v2::Config;
#[derive(Debug, PartialEq)]
pub enum ConfigState {
Current,
Upgraded,
}
pub trait ConfigTrait: DeserializeOwned + Serialize + Sized {
type Previous: ConfigTrait + Into<Self>;
fn new(filename: &Path) -> Result<(Self, ConfigState), Error> {
parse_toml(filename)
.map(|c| (c, ConfigState::Current))
.or_else(|e| {
Self::Previous::new(filename)
.map(|(c, _)| {
debug!("Upgrading from older config version");
(c.into(), ConfigState::Upgraded)
})
.map_err(|_| e)
})
}
fn targets(&self) -> Vec<Target>;
fn save(&self, path: &Path) -> Result<(), Error> {
let mut f = File::create(path)?;
write!(f, "{}", toml::to_string(&self)?)?;
Ok(())
}
}
#[derive(Serialize, Deserialize)]
pub struct EmptyConfig;
impl ConfigTrait for EmptyConfig {
type Previous = EmptyConfig;
fn new(_: &Path) -> Result<(Self, ConfigState), Error> {
Err(Error::Config)
}
fn targets(&self) -> Vec<Target> {
Vec::new()
}
fn save(&self, _: &Path) -> Result<(), Error> {
Err(Error::Config)
}
}
#[derive(Serialize, Deserialize)]
pub struct TargetConfig {
libs: Vec<String>,
env: HashMap<String, String>,
}
fn add_target(targets: &mut Vec<Target>, os: OS, arch: Arch, tc: &TargetConfig) {
if let Ok(mut target) = Target::new(os.clone(), arch, None) {
target.add_libs(&tc.libs);
target.add_env(&tc.env);
targets.push(target);
}
}
fn build_os(targets: &mut Vec<Target>, os: OS, value: &HashMap<String, TargetConfig>) {
for (arch, tc) in value.iter() {
if let Ok(arc) = Arch::try_from(arch.as_ref()) {
add_target(targets, os.clone(), arc, tc);
} else {
debug!("{} is not a valid architecture!", arch);
}
}
}