137 lines
3.4 KiB
Rust
137 lines
3.4 KiB
Rust
use std::cell::RefCell;
|
|
use std::io::{BufWriter, Read, Write};
|
|
|
|
use super::Section;
|
|
|
|
#[derive(Debug)]
|
|
pub enum Error {
|
|
ReadData,
|
|
WriteData,
|
|
}
|
|
|
|
pub struct Request<'args, R, W>
|
|
where
|
|
R: Read,
|
|
W: Write,
|
|
{
|
|
pub reader: RefCell<R>,
|
|
pub writer: W,
|
|
pub sections: &'args [String],
|
|
}
|
|
|
|
pub fn execute<R, W>(req: Request<R, W>) -> Result<(), Error>
|
|
where
|
|
R: Read,
|
|
W: Write,
|
|
{
|
|
let mut content = String::new();
|
|
req.reader
|
|
.borrow_mut()
|
|
.read_to_string(&mut content)
|
|
.map_err(|_| Error::ReadData)?;
|
|
|
|
let mut writer = BufWriter::new(req.writer);
|
|
|
|
let choose_sections = req
|
|
.sections
|
|
.iter()
|
|
.map(|s| Section::from(s.as_str()))
|
|
.collect::<Vec<_>>();
|
|
|
|
dbg!(&choose_sections);
|
|
|
|
let choose_namespaces = choose_sections
|
|
.iter()
|
|
.map(|s| s.namespace.clone())
|
|
.collect::<Vec<_>>();
|
|
|
|
let mut current_sections: Option<Vec<Section>> = None;
|
|
|
|
for line in content.split_inclusive('\n') {
|
|
let new_line = if is_section_end(line) {
|
|
current_sections = None;
|
|
line.to_string()
|
|
} else if let Some(section_info) = line.strip_prefix("### ") {
|
|
current_sections = section_info
|
|
.split_whitespace()
|
|
.next()
|
|
.map(|r| r.split(',').map(Section::from).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)) {
|
|
String::from(trimmed_line)
|
|
} else {
|
|
format!("# {}", trimmed_line)
|
|
}
|
|
} else {
|
|
line.to_string()
|
|
};
|
|
|
|
dbg!(line, ¤t_sections, &new_line);
|
|
|
|
writer
|
|
.write_all(new_line.as_bytes())
|
|
.map_err(|_| Error::WriteData)?;
|
|
}
|
|
|
|
writer.flush().map_err(|_| Error::WriteData)
|
|
}
|
|
|
|
fn is_section_end(line: &str) -> bool {
|
|
line.trim().is_empty()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use std::cell::RefCell;
|
|
use std::io::Cursor;
|
|
|
|
const BASE_ENV: &str = include_str!("../../test_data/base_env");
|
|
|
|
fn make_test(input: &str, expected_output: &str, sections: Vec<&str>) {
|
|
let reader = RefCell::new(Cursor::new(input));
|
|
let mut output_data = vec![];
|
|
let writer = Cursor::new(&mut output_data);
|
|
|
|
match execute(Request {
|
|
reader,
|
|
writer,
|
|
sections: §ions.into_iter().map(String::from).collect::<Vec<_>>(),
|
|
}) {
|
|
Ok(()) => {
|
|
let output = String::from_utf8(output_data).unwrap();
|
|
assert_eq!(
|
|
output.lines().collect::<Vec<_>>(),
|
|
expected_output.lines().collect::<Vec<_>>()
|
|
);
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn should_disable_all_sections() {
|
|
make_test(include_str!("../../test_data/all_env"), BASE_ENV, vec![]);
|
|
}
|
|
|
|
#[test]
|
|
fn should_enable_local_sections() {
|
|
make_test(
|
|
BASE_ENV,
|
|
include_str!("../../test_data/should_enable_local"),
|
|
vec!["local"],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn should_enable_staging_sections() {
|
|
make_test(
|
|
BASE_ENV,
|
|
include_str!("../../test_data/should_enable_staging"),
|
|
vec!["staging"],
|
|
);
|
|
}
|
|
}
|