1mod ser;
2pub use ser::{to_string, Serializer};
3
4use indexmap::IndexMap;
5use serde::Serialize;
6use serde_repr::Serialize_repr;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
9pub struct PBXObjectID(usize);
10
11#[derive(Debug, Serialize)]
12#[serde(untagged)]
13pub enum PBXSetting {
14 List(Vec<String>),
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr)]
18#[repr(u32)]
19pub enum PBXDstSubfolderSpec {
20 Wrapper = 1,
21 Executables = 6,
22 Resources = 7,
23 Frameworks = 10,
24 SharedFrameworks = 11,
25 SharedSupport = 12,
26 Plugins = 13,
27}
28
29#[derive(Debug, Serialize)]
30#[serde(tag = "isa")]
31pub enum PBXObject {
32 #[serde(rename_all = "camelCase")]
33 PBXFileReference {
34 path: String,
35 explicit_file_type: String,
36 source_tree: String,
37 },
38 #[serde(rename_all = "camelCase")]
39 PBXBuildFile {
40 file_ref: PBXObjectID,
41 settings: IndexMap<String, PBXSetting>,
42 },
43 #[serde(rename_all = "camelCase")]
44 PBXProject {
45 build_configuration_list: PBXObjectID,
46 targets: Vec<PBXObjectID>,
47 },
48 #[serde(rename_all = "camelCase")]
49 PBXNativeTarget {
50 name: String,
51 product_name: String,
52 product_reference: PBXObjectID,
53 product_type: String,
54 build_configuration_list: PBXObjectID,
55 build_phases: Vec<PBXObjectID>,
56 build_rules: Vec<PBXObjectID>,
57 dependencies: Vec<PBXObjectID>,
58 },
59 #[serde(rename_all = "camelCase")]
60 XCBuildConfiguration {
61 name: String,
62 build_settings: IndexMap<String, String>,
63 },
64 #[serde(rename_all = "camelCase")]
65 XCConfigurationList { build_configurations: Vec<PBXObjectID> },
66 #[serde(rename_all = "camelCase")]
67 PBXSourcesBuildPhase { files: Vec<PBXObjectID> },
68 #[serde(rename_all = "camelCase")]
69 PBXFrameworksBuildPhase { files: Vec<PBXObjectID> },
70 #[serde(rename_all = "camelCase")]
71 PBXShellScriptBuildPhase { shell_path: String, shell_script: String },
72 #[serde(rename_all = "camelCase")]
73 PBXCopyFilesBuildPhase {
74 files: Vec<PBXObjectID>,
75 dst_path: String,
76 dst_subfolder_spec: PBXDstSubfolderSpec,
77 },
78 #[serde(rename_all = "camelCase")]
79 PBXResourcesBuildPhase { files: Vec<PBXObjectID> },
80}
81
82#[derive(Debug, Serialize)]
83#[serde(rename_all = "camelCase")]
84pub struct PBXProject {
85 archive_version: i32,
86 object_version: i32,
87 objects: IndexMap<PBXObjectID, PBXObject>,
88 root_object: Option<PBXObjectID>,
89}
90
91impl Default for PBXProject {
92 fn default() -> Self {
93 Self::new(1, 55)
94 }
95}
96
97impl PBXProject {
98 pub fn new(archive_version: i32, object_version: i32) -> Self {
99 Self {
100 archive_version,
101 object_version,
102 objects: IndexMap::new(),
103 root_object: None,
104 }
105 }
106
107 pub fn add_object(&mut self, object: PBXObject) -> PBXObjectID {
108 let id = PBXObjectID(self.objects.len());
109 self.objects.insert(id, object);
110 id
111 }
112
113 pub fn set_root_object(&mut self, object_id: PBXObjectID) {
114 self.root_object = Some(object_id);
115 }
116}
117
118pub fn build_settings<const N: usize>(arr: [(&'static str, &'static str); N]) -> IndexMap<String, String> {
119 arr.iter().map(|(k, v)| ((*k).to_owned(), (*v).to_owned())).collect()
120}