summaryrefslogtreecommitdiffstats
path: root/third_party/rust/bindgen/deps.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/bindgen/deps.rs')
-rw-r--r--third_party/rust/bindgen/deps.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/third_party/rust/bindgen/deps.rs b/third_party/rust/bindgen/deps.rs
new file mode 100644
index 0000000000..be31f92896
--- /dev/null
+++ b/third_party/rust/bindgen/deps.rs
@@ -0,0 +1,61 @@
+/// Generating build depfiles from parsed bindings.
+use std::{collections::BTreeSet, path::PathBuf};
+
+#[derive(Clone, Debug)]
+pub(crate) struct DepfileSpec {
+ pub output_module: String,
+ pub depfile_path: PathBuf,
+}
+
+impl DepfileSpec {
+ pub fn write(&self, deps: &BTreeSet<Box<str>>) -> std::io::Result<()> {
+ std::fs::write(&self.depfile_path, self.to_string(deps))
+ }
+
+ fn to_string(&self, deps: &BTreeSet<Box<str>>) -> String {
+ // Transforms a string by escaping spaces and backslashes.
+ let escape = |s: &str| s.replace('\\', "\\\\").replace(' ', "\\ ");
+
+ let mut buf = format!("{}:", escape(&self.output_module));
+ for file in deps {
+ buf = format!("{} {}", buf, escape(file));
+ }
+ buf
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn escaping_depfile() {
+ let spec = DepfileSpec {
+ output_module: "Mod Name".to_owned(),
+ depfile_path: PathBuf::new(),
+ };
+
+ let deps: BTreeSet<_> = vec![
+ r"/absolute/path".into(),
+ r"C:\win\absolute\path".into(),
+ r"../relative/path".into(),
+ r"..\win\relative\path".into(),
+ r"../path/with spaces/in/it".into(),
+ r"..\win\path\with spaces\in\it".into(),
+ r"path\with/mixed\separators".into(),
+ ]
+ .into_iter()
+ .collect();
+ assert_eq!(
+ spec.to_string(&deps),
+ "Mod\\ Name: \
+ ../path/with\\ spaces/in/it \
+ ../relative/path \
+ ..\\\\win\\\\path\\\\with\\ spaces\\\\in\\\\it \
+ ..\\\\win\\\\relative\\\\path \
+ /absolute/path \
+ C:\\\\win\\\\absolute\\\\path \
+ path\\\\with/mixed\\\\separators"
+ );
+ }
+}