corge/
config.rs

1use anyhow::Result;
2use clap::ValueEnum;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use crate::cli::BuildToolchain;
6
7#[derive(Serialize, Deserialize, ValueEnum, Debug, Default, Clone)]
8pub enum LinkStrategy {
9    #[default]
10    Executable,
11    StaticLibrary,
12    DynamicLibrary,
13}
14
15impl LinkStrategy {
16    pub fn to_yaml_tag(&self) -> String {
17        match self {
18            LinkStrategy::Executable => "!Executable".to_string(),
19            LinkStrategy::StaticLibrary => "!StaticLibrary".to_string(),
20            LinkStrategy::DynamicLibrary => "!DynamicLibrary".to_string(),
21        }
22    }
23}
24
25#[derive(Serialize, Deserialize, Debug, Default)]
26pub struct Project {
27    pub name: String,
28    pub version: String,
29}
30
31#[derive(Serialize, Deserialize, Debug, Clone)]
32pub enum OptimizationLevel {
33    None,
34    O,
35    O1,
36    O2,
37    O3,
38    O0,
39    Os,
40    Ofast,
41    Og,
42    Oz,
43}
44
45impl OptimizationLevel {
46    pub fn as_gcc_flag(&self) -> Option<&str> {
47        match self {
48            OptimizationLevel::None => None,
49            OptimizationLevel::O => Some("-O"),
50            OptimizationLevel::O1 => Some("-O1"),
51            OptimizationLevel::O2 => Some("-O2"),
52            OptimizationLevel::O3 => Some("-O3"),
53            OptimizationLevel::O0 => Some("-O0"),
54            OptimizationLevel::Os => Some("-Os"),
55            OptimizationLevel::Ofast => Some("-Ofast"),
56            OptimizationLevel::Og => Some("-Og"),
57            OptimizationLevel::Oz => Some("-Oz"),
58        }
59    }
60}
61
62#[derive(Serialize, Deserialize, Debug, Clone)]
63pub struct Profile {
64    /// https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
65    pub optimization_level: OptimizationLevel,
66}
67
68#[derive(Serialize, Deserialize, Debug, Default, Clone)]
69pub struct Profiles {
70    pub release: Option<Profile>,
71    pub development: Option<Profile>,
72}
73
74#[derive(Serialize, Deserialize, Debug)]
75pub enum Registry {
76    Git {
77        url: String,
78        branch: String,
79    },
80    FileSystem(String),
81}
82
83
84#[derive(Serialize, Deserialize, Debug, Default, Clone)]
85pub struct Dependency {
86    pub name: String,
87    pub registry_name: String,
88}
89
90#[derive(Serialize, Deserialize, Clone, Debug)]
91pub struct Toolchain {
92    pub compiler: String,
93    pub archiver: String,
94    pub compiler_flags: Vec<String>,
95    pub linker_flags: Vec<String>,
96}
97impl Default for Toolchain {
98    fn default() -> Self {
99        Self {
100            compiler: "gcc".to_string(),
101            archiver: "ar".to_string(),
102            compiler_flags: vec![],
103            linker_flags: vec![],
104        }
105    }
106}
107
108#[derive(Serialize, Deserialize, Debug, Default)]
109pub struct Config {
110    pub project: Project,
111    #[serde(default)]
112    pub profiles: Profiles,
113    #[serde(default)]
114    pub registries: HashMap<String, Registry>,
115    #[serde(default)]
116    pub dependencies: Vec<Dependency>,
117    #[serde(default)]
118    pub toolchains: HashMap<String, Toolchain>
119}
120
121impl Config {
122    /** Returns the toolchain name on an error case */
123    pub fn toolchain(&self, toolchain: Option<BuildToolchain>) -> Result<(String, Toolchain)> {
124        // let toolchain = toolchain.map(|toolchain| toolchain.0);
125
126        match toolchain {
127            None | Some(BuildToolchain::Default) => {
128                let name = "default".to_string();
129                let toolchain = Toolchain::default();
130
131                Ok((name, toolchain))
132            }
133            Some(BuildToolchain::Named { name }) => {
134                let toolchain = self.toolchains
135                    .get(&name)
136                    .cloned()
137                    .ok_or_else(|| anyhow::anyhow!("Toolchain '{}' not found", name))?;
138
139                Ok((name, toolchain))
140            }
141            Some(BuildToolchain::Custom { compiler, archiver, compiler_flags, linker_flags }) => {
142                let name = "custom".to_string();
143                let toolchain = Toolchain {
144                    compiler,
145                    archiver,
146                    compiler_flags,
147                    linker_flags,
148                };
149
150                Ok((name, toolchain))
151            }
152        }
153    }
154}