serde_pbx/
lib.rs

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}