diff --git a/cli/src/main.rs b/cli/src/main.rs index 937b0080..68e75e94 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -89,36 +89,6 @@ fn main() -> anyhow::Result<()> { }, }; - let mut types = TypesBuilder::new(); - types - .add("rust", "*.rs") - .context("Failed to add rust type extensions")?; - types.select("rust"); - - // This is guaranteed to always have at least one value by the clap configuration - let first_root = directories - .first() - .expect("directories is empty; this shouldn't be possible"); - - let overrides = OverrideBuilder::new(first_root) - // Don't process files inside of tools/typeshare/ - .add("!**/tools/typeshare/**") - .context("Failed to parse override")? - .build() - .context("Failed to build override")?; - - let mut walker_builder = WalkBuilder::new(first_root); - // Sort walker output for deterministic output across platforms - walker_builder - .sort_by_file_path(Path::cmp) - .types(types.build().context("Failed to build types")?) - .overrides(overrides) - .follow_links(options.follow_links); - - for root in directories.iter().skip(1) { - walker_builder.add(root); - } - let destination = if let Some(ref file) = options.output.file { Output::File(file) } else if let Some(ref folder) = options.output.folder { @@ -140,13 +110,17 @@ fn main() -> anyhow::Result<()> { target_os, }; - let parsed_data = parallel_parse(&parse_context, walker_builder, language_type); + let mut parsed_data = parallel_parse( + &parse_context, + walker_builder(directories, &options)?, + language_type, + ); // Collect all the types into a map of the file name they // belong too and the list of type names. Used for generating // imports in generated files. let import_candidates = if multi_file { - all_types(&parsed_data) + all_types(&mut parsed_data) } else { HashMap::new() }; @@ -161,6 +135,37 @@ fn main() -> anyhow::Result<()> { Ok(()) } +fn walker_builder( + directories: &[std::path::PathBuf], + options: &Args, +) -> anyhow::Result { + let mut types = TypesBuilder::new(); + types + .add("rust", "*.rs") + .context("Failed to add rust type extensions")?; + types.select("rust"); + + let first_root = directories + .first() + .expect("directories is empty; this shouldn't be possible"); + let overrides = OverrideBuilder::new(first_root) + // Don't process files inside of tools/typeshare/ + .add("!**/tools/typeshare/**") + .context("Failed to parse override")? + .build() + .context("Failed to build override")?; + let mut walker_builder = WalkBuilder::new(first_root); + walker_builder + .sort_by_file_path(Path::cmp) + .types(types.build().context("Failed to build types")?) + .overrides(overrides) + .follow_links(options.follow_links); + for root in directories.iter().skip(1) { + walker_builder.add(root); + } + Ok(walker_builder) +} + /// Get the language trait impl for the given supported language and configuration. fn language( language_type: SupportedLanguage, diff --git a/cli/src/parse.rs b/cli/src/parse.rs index da64950b..d989d678 100644 --- a/cli/src/parse.rs +++ b/cli/src/parse.rs @@ -4,7 +4,8 @@ use crossbeam::channel::bounded; use ignore::{DirEntry, WalkBuilder, WalkState}; use log::error; use std::{ - collections::{hash_map::Entry, BTreeMap, HashMap}, + collections::{BTreeMap, HashMap}, + mem, ops::Not, path::PathBuf, thread, @@ -63,21 +64,17 @@ fn output_file_name(language_type: SupportedLanguage, crate_name: &CrateName) -> /// Collect all the typeshared types into a mapping of crate names to typeshared types. This /// mapping is used to lookup and generated import statements for generated files. -pub fn all_types(file_mappings: &BTreeMap) -> CrateTypes { +pub fn all_types(file_mappings: &mut BTreeMap) -> CrateTypes { file_mappings - .iter() - .map(|(crate_name, parsed_data)| (crate_name, parsed_data.type_names.clone())) + .iter_mut() + .map(|(crate_name, parsed_data)| (crate_name, mem::take(&mut parsed_data.type_names))) .fold( HashMap::new(), |mut import_map: CrateTypes, (crate_name, type_names)| { - match import_map.entry(crate_name.clone()) { - Entry::Occupied(mut e) => { - e.get_mut().extend(type_names); - } - Entry::Vacant(e) => { - e.insert(type_names); - } - } + import_map + .entry(crate_name.clone()) + .or_default() + .extend(type_names); import_map }, ) @@ -148,8 +145,9 @@ pub fn parallel_parse( Box::new(move |result| match result { Ok(dir_entry) => { - if let Some(result) = parse_dir_entry(parse_context, language_type, dir_entry) { - tx.send(result).unwrap(); + if let Some(parsed_data) = parse_dir_entry(parse_context, language_type, dir_entry) + { + tx.send(parsed_data).unwrap(); } WalkState::Continue }