Skip to main content

cargo_xcode_build_rs/
config.rs

1use crate::prelude::*;
2
3#[derive(Deserialize, Debug, Default)]
4#[serde(deny_unknown_fields)]
5pub struct Config {
6	/// What features to enable for iOS builds
7	#[serde(default)]
8	ios: Flags,
9}
10
11pub use flags::*;
12mod flags {
13	use crate::prelude::*;
14
15	#[derive(Debug, Deserialize, Clone)]
16	pub struct Flags {
17		#[serde(default)]
18		features: Vec<String>,
19		/// Whether or not to pass the flag `--no-default-features` to `cargo rustc`
20		/// See https://doc.rust-lang.org/cargo/reference/features.html#command-line-feature-options
21		#[serde(
22			default = "Flags::default_default_features",
23			rename = "default-features"
24		)]
25		default_features: bool,
26		/// Passed to `cargo rustc`
27		/// E.g.
28		/// ```toml
29		/// extra_flags = ["--cfg", "winit_ignore_noise_logs_unstable"]
30		/// ```
31		#[serde(default, rename = "extra-flags")]
32		extra_flags: Vec<String>,
33	}
34
35	impl Flags {
36		/// Default for [Self::default_features]
37		fn default_default_features() -> bool {
38			true
39		}
40	}
41
42	impl Flags {
43		pub fn into_args(&self) -> Vec<String> {
44			let mut args = vec![];
45			if !self.default_features {
46				args.push("--no-default-features".into());
47			}
48			for feature in self.features.iter() {
49				args.push("--features".into());
50				args.push(feature.clone());
51			}
52			for extra_flags in self.extra_flags.iter() {
53				args.push(extra_flags.clone());
54			}
55			args
56		}
57	}
58
59	impl Default for Flags {
60		fn default() -> Self {
61			Flags {
62				default_features: Flags::default_default_features(),
63				features: Default::default(),
64				extra_flags: Default::default(),
65			}
66		}
67	}
68
69	// #[cfg(test)]
70	// mod tests {
71	// 	use super::*;
72
73	// 	fn test_basic_toml() {
74	// 		let raw_toml: r##"
75	// 		[package.metadata.xcode-build-rs.ios]
76
77	// 		"##
78	// 	}
79	// }
80}
81
82impl Config {
83	pub fn retrieve_from_toml_config(manifest_path: &Utf8Path) -> Result<Config, Report> {
84		match std::fs::read_to_string(manifest_path) {
85			Err(err) => {
86				info!(
87					message = "Cannot find `Cargo.toml` file in manifest_dir, using default config",
88					?err,
89					?manifest_path
90				);
91				Ok(Config::default())
92			}
93			Ok(config) => {
94				let raw_config: toml::Value = toml::from_str(&config)
95					.wrap_err_with(|| format!("Cannot parse Cargo.toml file: {:?}", manifest_path))?;
96				let config = raw_config
97					.get("package")
98					.and_then(|package| package.get("metadata"))
99					.and_then(|metadata| metadata.get("xcode-build-rs"));
100				match config {
101					None => {
102						info!(?manifest_path, "Using default config since `package.metadata.xcode_build_rs` section is missing from Cargo.toml");
103						Ok(Config::default())
104					}
105					Some(toml_config) => {
106						let config: Config = toml_config
107							.clone()
108							.try_into()
109							.wrap_err("Cannot deserialize `xcode-build-rs` section of Cargo.toml")?;
110						info!(message = "Deserialized Config from Cargo.toml", ?config, ?manifest_path, cwd = ?cwd()?, ?toml_config);
111						Ok(config)
112					}
113				}
114			}
115		}
116	}
117
118	pub fn ios_feature_flags(&self) -> Flags {
119		self.ios.clone()
120	}
121}