diff --git a/src/domain.rs b/src/domain.rs index cfa1899..0898b8b 100644 --- a/src/domain.rs +++ b/src/domain.rs @@ -1,26 +1,29 @@ pub mod switch; -#[derive(Debug, Clone, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] struct Section { namespace: Option, name: String, } -impl<'a> From<&'a str> for Section { - fn from(s: &'a str) -> Self { - let (ns, name) = s - .trim() - .split_once(':') - .map_or_else(|| (None, s), |(ns, name)| (Some(ns), name)); +impl Section { + fn new(name: &str) -> Self { Self { - namespace: ns.map(String::from), - name: String::from(name), + name: name.to_string(), + namespace: None, } } -} -impl PartialEq for Section { - fn eq(&self, other: &Self) -> bool { - self.name == other.name && (self.namespace.is_none() || self.namespace == other.namespace) + fn with_namespace(namespace: &str, name: &str) -> Self { + Self { + name: name.to_string(), + namespace: Some(namespace.to_string()), + } + } + + fn parse(s: &str) -> Self { + let s = s.trim(); + s.split_once(':') + .map_or_else(|| Self::new(s), |(ns, name)| Self::with_namespace(ns, name)) } } diff --git a/src/domain/switch.rs b/src/domain/switch.rs index 0f0089c..7c1df5e 100644 --- a/src/domain/switch.rs +++ b/src/domain/switch.rs @@ -35,14 +35,7 @@ where let choose_sections = req .sections .iter() - .map(|s| Section::from(s.as_str())) - .collect::>(); - - dbg!(&choose_sections); - - let choose_namespaces = choose_sections - .iter() - .map(|s| s.namespace.clone()) + .map(|s| Section::parse(s.as_str())) .collect::>(); let mut current_sections: Option> = None; @@ -55,11 +48,11 @@ where current_sections = section_info .split_whitespace() .next() - .map(|r| r.split(',').map(Section::from).collect()); + .map(|r| r.split(',').map(Section::parse).collect()); line.to_string() } else if let Some(cur_sections) = current_sections.clone() { let trimmed_line = line.trim_start_matches(['#', ' ']); - if cur_sections.iter().any(|s| choose_sections.contains(s)) { + if should_enable_variable(&choose_sections, &cur_sections) { String::from(trimmed_line) } else { format!("# {}", trimmed_line) @@ -68,8 +61,6 @@ where line.to_string() }; - dbg!(line, ¤t_sections, &new_line); - writer .write_all(new_line.as_bytes()) .map_err(|_| Error::WriteData)?; @@ -82,6 +73,30 @@ fn is_section_end(line: &str) -> bool { line.trim().is_empty() } +fn should_enable_variable(choose_sections: &[Section], current_sections: &[Section]) -> bool { + let cross_sections = choose_sections + .iter() + .filter(|s| { + s.namespace.is_some() + && current_sections + .iter() + .any(|s2| s.namespace == s2.namespace) + }) + .collect::>(); + + if cross_sections.is_empty() { + choose_sections.iter().any(|s| { + if s.namespace.is_none() { + current_sections.iter().any(|s2| s.name == s2.name) + } else { + current_sections.contains(s) + } + }) + } else { + cross_sections.iter().any(|s| current_sections.contains(s)) + } +} + #[cfg(test)] mod tests { use super::*; @@ -133,4 +148,78 @@ mod tests { vec!["staging"], ); } + + #[test] + fn should_use_debug_in_staging_section() { + make_test( + BASE_ENV, + include_str!("../../test_data/should_use_debug_in_staging"), + vec!["staging", "debug:on"], + ); + } + + #[test] + fn should_use_staging_db_in_local_section() { + make_test( + BASE_ENV, + include_str!("../../test_data/should_use_staging_db_in_local"), + vec!["local", "db:staging"], + ); + } + + mod utils { + use super::*; + + #[test] + fn should_not_enable_variables() { + assert!(!should_enable_variable( + &[Section::new("local")], + &[Section::new("staging")] + )); + assert!(!should_enable_variable( + &[Section::with_namespace("db", "local")], + &[Section::new("local")] + )); + assert!(!should_enable_variable( + &[Section::with_namespace("db", "local")], + &[Section::with_namespace("db", "staging")] + )); + assert!(!should_enable_variable( + &[ + Section::new("staging"), + Section::with_namespace("debug", "on") + ], + &[ + Section::with_namespace("debug", "off"), + Section::new("staging") + ] + )); + } + + #[test] + fn should_enable_variables() { + assert!(should_enable_variable( + &[Section::new("local")], + &[Section::new("local")] + )); + assert!(should_enable_variable( + &[Section::new("local")], + &[Section::with_namespace("db", "local")] + )); + assert!(should_enable_variable( + &[Section::with_namespace("db", "local")], + &[Section::with_namespace("db", "local")] + )); + assert!(should_enable_variable( + &[ + Section::new("local"), + Section::with_namespace("debug", "on") + ], + &[ + Section::with_namespace("debug", "on"), + Section::new("staging") + ] + )); + } + } }