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 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 pub fn toolchain(&self, toolchain: Option<BuildToolchain>) -> Result<(String, Toolchain)> {
124 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}