add namespaces #8

Merged
pleshevskiy merged 4 commits from namespace into main 2022-07-31 00:55:31 +03:00
2 changed files with 117 additions and 25 deletions
Showing only changes of commit 8fed9f979b - Show all commits

View file

@ -1,26 +1,29 @@
pub mod switch; pub mod switch;
#[derive(Debug, Clone, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
struct Section { struct Section {
namespace: Option<String>, namespace: Option<String>,
name: String, name: String,
} }
impl<'a> From<&'a str> for Section { impl Section {
fn from(s: &'a str) -> Self { fn new(name: &str) -> Self {
let (ns, name) = s
.trim()
.split_once(':')
.map_or_else(|| (None, s), |(ns, name)| (Some(ns), name));
Self { Self {
namespace: ns.map(String::from), name: name.to_string(),
name: String::from(name), namespace: None,
} }
} }
}
impl PartialEq for Section { fn with_namespace(namespace: &str, name: &str) -> Self {
fn eq(&self, other: &Self) -> bool { Self {
self.name == other.name && (self.namespace.is_none() || self.namespace == other.namespace) 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))
} }
} }

View file

@ -35,14 +35,7 @@ where
let choose_sections = req let choose_sections = req
.sections .sections
.iter() .iter()
.map(|s| Section::from(s.as_str())) .map(|s| Section::parse(s.as_str()))
.collect::<Vec<_>>();
dbg!(&choose_sections);
let choose_namespaces = choose_sections
.iter()
.map(|s| s.namespace.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut current_sections: Option<Vec<Section>> = None; let mut current_sections: Option<Vec<Section>> = None;
@ -55,11 +48,11 @@ where
current_sections = section_info current_sections = section_info
.split_whitespace() .split_whitespace()
.next() .next()
.map(|r| r.split(',').map(Section::from).collect()); .map(|r| r.split(',').map(Section::parse).collect());
line.to_string() line.to_string()
} else if let Some(cur_sections) = current_sections.clone() { } else if let Some(cur_sections) = current_sections.clone() {
let trimmed_line = line.trim_start_matches(['#', ' ']); 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) String::from(trimmed_line)
} else { } else {
format!("# {}", trimmed_line) format!("# {}", trimmed_line)
@ -68,8 +61,6 @@ where
line.to_string() line.to_string()
}; };
dbg!(line, &current_sections, &new_line);
writer writer
.write_all(new_line.as_bytes()) .write_all(new_line.as_bytes())
.map_err(|_| Error::WriteData)?; .map_err(|_| Error::WriteData)?;
@ -82,6 +73,30 @@ fn is_section_end(line: &str) -> bool {
line.trim().is_empty() 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::<Vec<_>>();
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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -133,4 +148,78 @@ mod tests {
vec!["staging"], 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")
]
));
}
}
} }