diff options
Diffstat (limited to 'third_party/rust/bindgen/deps.rs')
-rw-r--r-- | third_party/rust/bindgen/deps.rs | 61 |
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" + ); + } +} |