1
//! The higher abstractions of the program
2

            
3
use crate::domain::commands::arguments::Argument;
4
use crate::domain::commands::command_lines::{LinkerCommandLine, SourceCommandLine};
5
use crate::project_model::sourceset::SourceSet;
6
use serde::{Deserialize, Serialize};
7
use std::borrow::Cow;
8

            
9
/// The final product that will be made after the building process
10
4
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
11
pub struct Target<'a> {
12
    pub sources: Vec<SourceCommandLine<'a>>,
13
    pub linker: LinkerCommandLine<'a>,
14
    pub kind: TargetKind,
15
    pub enabled_for_current_program_iteration: bool,
16
}
17

            
18
impl<'a> Target<'a> {
19
    /// Defaults initializes a new [`Target`] when the unique data
20
    /// is the [`TargetKind`]. This is useful in our internals when there's
21
    /// no entry for this target on the [`ZorkCache`] and we want to create a new
22
    /// one in place to add a new [`SourceCommandLine`]
23
12
    pub fn new_default_for_kind(kind: TargetKind) -> Self {
24
12
        Self {
25
12
            sources: Vec::default(),
26
12
            linker: LinkerCommandLine::default(),
27
            kind,
28
            enabled_for_current_program_iteration: true,
29
        }
30
12
    }
31
}
32

            
33
/// Strong type for storing the target unique identifier, which instead of being
34
/// composite within the [`Target`] struct, is externalized in this wrapped type, so
35
/// we can use a strong type on the [`Commands.targets`] container
36
294
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, Hash, Clone)]
37
143
pub struct TargetIdentifier<'a>(pub Cow<'a, str>);
38

            
39
impl<'a> From<&'a str> for TargetIdentifier<'a> {
40
5
    fn from(value: &'a str) -> Self {
41
5
        Self(Cow::Borrowed(value))
42
5
    }
43
}
44

            
45
impl<'a> TargetIdentifier<'a> {
46
    #[inline(always)]
47
19
    pub fn name(&'a self) -> &'a str {
48
19
        self.0.as_ref()
49
19
    }
50
}
51

            
52
/// The different types of final products
53
49
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, Copy, Clone)]
54
1
pub enum TargetKind {
55
    #[default]
56
    #[serde(alias = "Executable", alias = "executable", alias = "exe")]
57
17
    Executable,
58
    #[serde(
59
        alias = "StaticLib",
60
        alias = "static lib",
61
        alias = "static-lib",
62
        alias = "static_lib",
63
        alias = "staticlib"
64
    )]
65
    StaticLib,
66
    #[serde(
67
        alias = "DynamicLib",
68
        alias = "dynamic lib",
69
        alias = "dyn-lib",
70
        alias = "dyn_lib",
71
        alias = "dylib"
72
    )]
73
    DyLib,
74
}
75

            
76
/// Bound for the user defined arguments that are passed to the compiler
77
pub trait ExtraArgs<'a> {
78
    fn extra_args(&'a self) -> &'a [Argument];
79
}
80

            
81
/// Contracts for the executable operations
82
pub trait ExecutableTarget<'a>: ExtraArgs<'a> {
83
    fn name(&'a self) -> &'a str;
84
    fn sourceset(&'a self) -> &'a SourceSet;
85
}