1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Project {
    /// Name of the generated project.
    pub name: String,

    /// The list of targets in the project mapped by name.
    pub targets: HashMap<String, Target>,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct Target {
    /// Product type of the target.
    #[serde(rename = "type")]
    pub product_type: ProductType,

    /// Platform of the target.
    pub platform: HashSet<Platform>,

    /// The deployment target (e.g. `9.2`). If this is not specified the value
    /// from the project set in `Options.deploymentTarget.PLATFORM` will be used.
    #[serde(rename = "deploymentTarget")]
    pub deployment_targets: HashMap<Platform, String>,

    /// Source directories of the target.
    pub sources: Vec<TargetSource>,

    /// Target specific build settings. Default platform and product type
    /// settings will be applied first before any custom settings defined here.
    /// Other context dependant settings will be set automatically as well.
    pub settings: HashMap<String, String>,

    /// Dependencies for the target.
    pub dependencies: Vec<Dependency>,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum ProductType {
    #[serde(rename = "application")]
    Application,

    #[serde(rename = "application-on-demand-install-capable")]
    ApplicationOnDemandInstallCapable,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum Platform {
    #[serde(rename = "iOS")]
    IOS,

    #[serde(rename = "macOS")]
    MacOS,

    #[serde(rename = "tvOS")]
    TVOS,

    #[serde(rename = "watchOS")]
    WatchOS,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct TargetSource {
    /// The path of the source file or directory.
    pub path: String,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Dependency {
    Framework { framework: String, embed: bool },
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_spec() {
        let project = Project {
            name: "Example".to_owned(),
            targets: vec![(
                "Example".to_owned(),
                Target {
                    product_type: ProductType::Application,
                    platform: vec![Platform::IOS].into_iter().collect(),
                    deployment_targets: vec![(Platform::IOS, "8.0".to_owned())]
                        .into_iter()
                        .collect(),
                    sources: vec![TargetSource {
                        path: "Sources".to_owned(),
                    }],
                    settings: vec![
                        (
                            "LIBRARY_SEARCH_PATHS".to_owned(),
                            "../x86_64-apple-ios/debug".to_owned(),
                        ),
                        ("OTHER_LDFLAGS".to_owned(), "-ObjC".to_owned()),
                    ]
                    .into_iter()
                    .collect(),
                    dependencies: vec![Dependency::Framework {
                        framework: "libexample.a".to_owned(),
                        embed: false,
                    }],
                },
            )]
            .into_iter()
            .collect(),
        };

        let result = serde_yaml::to_string(&project).unwrap();
        println!("Result: {}", result);
    }
}