release_manager/config/
mod.rs

1// This file is part of Release Manager
2
3// Release Manager is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7
8// Release Manager is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12
13// You should have received a copy of the GNU General Public License
14// along with Release Manager  If not, see <http://www.gnu.org/licenses/>.
15
16use std::convert::TryFrom;
17use std::collections::HashMap;
18use std::path::Path;
19use std::fs::File;
20use std::io::Write;
21use serde::de::DeserializeOwned;
22use serde::ser::Serialize;
23use toml;
24
25use super::{Arch, OS, Target, Error};
26use super::parse_toml;
27
28mod v0;
29mod v1;
30mod v2;
31
32pub use self::v2::Config;
33
34#[derive(Debug, PartialEq)]
35pub enum ConfigState {
36    Current,
37    Upgraded,
38}
39
40pub trait ConfigTrait: DeserializeOwned + Serialize + Sized {
41    type Previous: ConfigTrait + Into<Self>;
42
43    fn new(filename: &Path) -> Result<(Self, ConfigState), Error> {
44        parse_toml(filename)
45            .map(|c| (c, ConfigState::Current))
46            .or_else(|e| {
47                Self::Previous::new(filename)
48                    .map(|(c, _)| {
49                        debug!("Upgrading from older config version");
50                        (c.into(), ConfigState::Upgraded)
51                    })
52                    .map_err(|_| e)
53            })
54    }
55
56    fn targets(&self) -> Vec<Target>;
57
58    fn save(&self, path: &Path) -> Result<(), Error> {
59        let mut f = File::create(path)?;
60        write!(f, "{}", toml::to_string(&self)?)?;
61
62        Ok(())
63    }
64}
65
66#[derive(Serialize, Deserialize)]
67pub struct EmptyConfig;
68
69impl ConfigTrait for EmptyConfig {
70    type Previous = EmptyConfig;
71
72    fn new(_: &Path) -> Result<(Self, ConfigState), Error> {
73        Err(Error::Config)
74    }
75
76    fn targets(&self) -> Vec<Target> {
77        Vec::new()
78    }
79
80    fn save(&self, _: &Path) -> Result<(), Error> {
81        Err(Error::Config)
82    }
83}
84
85#[derive(Serialize, Deserialize)]
86pub struct TargetConfig {
87    libs: Vec<String>,
88    env: HashMap<String, String>,
89}
90
91fn add_target(targets: &mut Vec<Target>, os: OS, arch: Arch, tc: &TargetConfig) {
92    if let Ok(mut target) = Target::new(os.clone(), arch, None) {
93        target.add_libs(&tc.libs);
94        target.add_env(&tc.env);
95        targets.push(target);
96    }
97}
98
99fn build_os(targets: &mut Vec<Target>, os: OS, value: &HashMap<String, TargetConfig>) {
100    for (arch, tc) in value.iter() {
101        if let Ok(arc) = Arch::try_from(arch.as_ref()) {
102            add_target(targets, os.clone(), arc, tc);
103        } else {
104            debug!("{} is not a valid architecture!", arch);
105        }
106    }
107}