1
//! root file for the crate where the datastructures that holds the TOML
2
//! parsed data lives.
3
pub mod build;
4
pub mod compiler;
5
pub mod modules;
6
pub mod project;
7
pub mod target;
8

            
9
use indexmap::IndexMap;
10
use serde::{Deserialize, Deserializer, Serialize};
11

            
12
use self::{
13
    build::BuildAttribute, compiler::CompilerAttribute, modules::ModulesAttribute,
14
    project::ProjectAttribute, target::TargetAttribute,
15
};
16

            
17
/// ```rust
18
/// use zork::config_file::{
19
///     ZorkConfigFile,
20
///     compiler::{CppCompiler, LanguageLevel},
21
///     target::TargetAttribute
22
/// };
23
/// use zork::domain::target::TargetKind;
24
/// use indexmap::IndexMap;
25
///
26
/// const CONFIG_FILE_MOCK: &str = r#"
27
///     [project]
28
///     name = 'Zork++ serde tests'
29
///     authors = ['zerodaycode.gz@gmail.com']
30
///
31
///     [compiler]
32
///     cpp_compiler = 'clang'
33
///     cpp_standard = '20'
34
///
35
///     [targets.executable]
36
///     output_name = 'final binary'
37
///     sources = [ 'main.cpp' ]
38
///     extra_args = [ '-Wall' ]
39
///
40
///     [targets.tests]
41
///     sources = [ 'tests_main.cpp' ]
42
///     target_kind = 'executable'
43

            
44
///     [targets.other_tests]
45
///     sources = [ 'other_tests_main.cpp' ]
46
///     target_kind = 'executable'
47
/// "#;
48
///
49
/// let config: ZorkConfigFile = toml::from_str(CONFIG_FILE_MOCK)
50
///     .expect("A failure happened parsing the Zork toml file");
51
///
52
/// let compiler_attribute = &config.compiler;
53
/// assert_eq!(compiler_attribute.cpp_compiler, CppCompiler::CLANG);
54
/// assert_eq!(compiler_attribute.cpp_standard, LanguageLevel::CPP20);
55
///
56
/// let targets: &IndexMap<&str, TargetAttribute<'_>> = &config.targets;
57
/// assert!(!targets.is_empty());
58
///
59
/// let executable_target: &TargetAttribute<'_> = targets.get("executable").expect("Target named
60
///     'executable' not found on the configuration");
61
/// assert!(executable_target.output_name.unwrap().contains("final binary"));
62
/// assert!(executable_target.sources.contains(&"main.cpp"));
63
/// assert!(executable_target.extra_args.as_ref().unwrap().contains(&"-Wall"));
64
/// assert!(executable_target.kind.unwrap_or_default().eq(&TargetKind::Executable));
65
///
66
/// let tests_target: &TargetAttribute<'_> = targets.get("tests").expect("Target named
67
///     'tests' not found on the configuration");
68
/// assert!(tests_target.sources.contains(&"tests_main.cpp"));
69
/// assert!(tests_target.extra_args.is_none());
70
/// assert!(tests_target.kind.unwrap_or_default().eq(&TargetKind::Executable));
71
///
72
/// let other_tests_target: &TargetAttribute<'_> = targets.get("other_tests").expect("Target named
73
///     'other_tests' not found on the configuration");
74
/// assert!(other_tests_target.sources.contains(&"other_tests_main.cpp"));
75
/// assert!(other_tests_target.extra_args.is_none());
76
/// assert!(other_tests_target.kind.unwrap_or_default().eq(&TargetKind::Executable));
77
/// ```
78
/// The [`ZorkConfigFile`] is the type that holds
79
/// the whole hierarchy of Zork++ config file attributes
80
/// and properties
81
156
#[derive(Serialize, Deserialize, Debug, Default)]
82
pub struct ZorkConfigFile<'a> {
83
    #[serde(borrow)]
84
    pub project: ProjectAttribute<'a>,
85
    #[serde(borrow)]
86
    pub compiler: CompilerAttribute<'a>,
87
    #[serde(borrow)]
88
    pub build: Option<BuildAttribute<'a>>,
89
    #[serde(borrow)]
90
    pub modules: Option<ModulesAttribute<'a>>,
91
    #[serde(deserialize_with = "deserialize_targets")]
92
    pub targets: IndexMap<&'a str, TargetAttribute<'a>>,
93
}
94

            
95
9
fn deserialize_targets<'de, D>(
96
    deserializer: D,
97
) -> Result<IndexMap<&'de str, TargetAttribute<'de>>, D::Error>
98
where
99
    D: Deserializer<'de>,
100
{
101
9
    let helper: IndexMap<&str, TargetAttribute> = Deserialize::deserialize(deserializer)?;
102
9
    Ok(helper)
103
9
}
104

            
105
8
pub fn zork_cfg_from_file(cfg: &'_ str) -> Result<ZorkConfigFile<'_>, toml::de::Error> {
106
8
    <ZorkConfigFile>::deserialize(&mut toml::Deserializer::new(cfg))
107
8
}