use structopt::StructOpt;
use batch_mode::*;
use batch_mode_3p::*;
use batch_mode_3p::io::AsyncReadExt;
#[derive(StructOpt, Debug)]
pub struct FileDifferenceArgs {
#[structopt(long,parse(from_os_str))]
file_a: PathBuf,
#[structopt(long,parse(from_os_str))]
file_b: PathBuf,
#[structopt(long,parse(from_os_str))]
file_c: PathBuf,
}
impl FileDifferenceArgs {
pub async fn run(
&self,
) -> Result<(), TokenParseError> {
let tokens_a = parse_token_file(self.file_a.to_str().unwrap()).await?;
let tokens_b = parse_token_file(self.file_b.to_str().unwrap()).await?;
info!("tokens_a, len={}", tokens_a.len());
info!("tokens_b, len={}", tokens_b.len());
let data_in_b: HashSet<String> = tokens_b
.into_iter()
.map(|token| token.name().to_string())
.collect();
info!("data_in_b, len={}", data_in_b.len());
let filtered_tokens: Vec<CamelCaseTokenWithComment> = tokens_a
.into_iter()
.filter(|token| !data_in_b.contains(&token.name().to_string()))
.collect();
info!("filtered_tokens, len={}", filtered_tokens.len());
let mut out_file = File::create(&self.file_c).await?;
for token in filtered_tokens {
let line = format!("{}\n", token);
out_file.write_all(line.as_bytes()).await?;
}
Ok(())
}
}
#[tokio::main]
pub async fn main() -> Result<(), TokenParseError> {
configure_tracing();
let args = FileDifferenceArgs::from_args();
args.run().await?;
Ok(())
}
#[cfg(test)]
mod test_file_difference_logic {
use super::*;
use tokio::io::AsyncWriteExt;
#[tokio::test]
async fn test_difference_of_files() -> Result<(), TokenParseError> {
let dir = tempfile::tempdir()?;
let path_a = dir.path().join("fileA.txt");
let path_b = dir.path().join("fileB.txt");
let path_c = dir.path().join("fileC.txt");
{
let mut file_a = File::create(&path_a).await?;
file_a.write_all(b"TokenA -- comment A\nTokenB -- comment B\nTokenC -- comment C\n").await?;
}
{
let mut file_b = File::create(&path_b).await?;
file_b.write_all(b"TokenA -- different comment\nTokenC -- another comment\n").await?;
}
let cli_args = FileDifferenceArgs {
file_a: path_a.clone(),
file_b: path_b.clone(),
file_c: path_c.clone(),
};
cli_args.run().await?;
let file_c = File::open(&path_c).await?;
let mut reader_c = BufReader::new(file_c);
let mut output = String::new();
reader_c.read_to_string(&mut output).await?;
assert!(output.contains("TokenB -- comment B"));
assert!(!output.contains("TokenA"));
assert!(!output.contains("TokenC"));
Ok(())
}
}