diff --git a/Cargo.lock b/Cargo.lock index bc29e4c..c6a3cf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ [[package]] name = "hoster" -version = "0.1.1" +version = "0.2.0" dependencies = [ "smallvec", "thiserror", @@ -110,7 +110,7 @@ dependencies = [ [[package]] name = "hosts-edit" -version = "0.1.1" +version = "0.2.0" dependencies = [ "clap", "hoster", diff --git a/hoster/Cargo.toml b/hoster/Cargo.toml index d0bb779..0c28e81 100644 --- a/hoster/Cargo.toml +++ b/hoster/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "hoster" -version = "0.1.1" +version = "0.2.0" edition = "2021" authors = ["Dusan Malusev "] description = "Small parser and lexer library for Hosts file format" categories = ["parsing", "filesystem", "development-tools"] -documentation = "https://docs.rs/hoster/0.1.1" +documentation = "https://docs.rs/hoster/0.2.0" homepage = "https://github.com/BrosSquad/hosts" keywords = [ "hosts", diff --git a/hosts-edit/Cargo.toml b/hosts-edit/Cargo.toml index a6f299a..4fc746a 100644 --- a/hosts-edit/Cargo.toml +++ b/hosts-edit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hosts-edit" -version = "0.1.1" +version = "0.2.0" edition = "2021" authors = ["Dusan Malusev "] categories = ["parsing", "filesystem", "development-tools"] diff --git a/hosts-edit/src/app.rs b/hosts-edit/src/app.rs index e5634e0..218a964 100644 --- a/hosts-edit/src/app.rs +++ b/hosts-edit/src/app.rs @@ -63,8 +63,11 @@ where let _n = hosts.write(&data)?; } Commands::List { with_comments } => { + let stdout = std::io::stdout(); + list_command( &mut file_options.append(false).read(true).open(path.into())?, + &mut stdout.lock(), with_comments, )?; } diff --git a/hosts-edit/src/commands/list.rs b/hosts-edit/src/commands/list.rs index f2c9112..7a46bc4 100644 --- a/hosts-edit/src/commands/list.rs +++ b/hosts-edit/src/commands/list.rs @@ -1,20 +1,26 @@ use std::error::Error; -use std::io::Read; +use std::io::{Read, Write}; use hoster::cst::CstNode; use hoster::parser::Parser; use hoster::tokenizer::Tokenizer; use hoster::visitor::CstVisitor; -pub(crate) fn execute(reader: &mut R, _with_comments: bool) -> Result<(), Box> +pub(crate) fn execute( + reader: &mut R, + output: &mut W, + _with_comments: bool, +) -> Result<(), Box> where R: Read, + W: Write, { let tokens = Tokenizer::new_with_reader(reader).parse()?.get_tokens(); let mut parser = Parser::builder() .visitor(Visitor { print_new_line: false, + output, }) .build(); @@ -24,25 +30,30 @@ where Ok(()) } -pub(crate) struct Visitor { +pub(crate) struct Visitor { print_new_line: bool, + output: W, } -impl CstVisitor for Visitor { +impl CstVisitor for Visitor +where + W: Write, +{ fn visit(&mut self, _idx: usize, node: &CstNode) -> Option<()> { match node { CstNode::Host(host) => { self.print_new_line = true; - print!("\t{}", host); + write!(self.output, "\t{}", host).unwrap(); } CstNode::IP(ip) => { - print!("{}", ip); + write!(self.output, "{}", ip).unwrap(); + self.print_new_line = false; } CstNode::NewLine => { if self.print_new_line { self.print_new_line = false; - println!(); + writeln!(self.output).unwrap(); } } _ => {} @@ -51,3 +62,46 @@ impl CstVisitor for Visitor { Some(()) } } + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use super::*; + + #[test] + fn test_list_without_comments() { + let mut output = Cursor::new(Vec::new()); + + let mut reader = Cursor::new( + "\ +# localhost name resolution is handled within DNS itself. +# Added by Docker Desktop +192.168.0.17\thost.docker.internal +192.168.0.17 gateway.docker.internal +# To allow the same kube context to work on the host and the container: +\t127.0.0.1\tkubernetes.docker.internal + + +# End of section +" + .to_string(), + ); + + let result = execute(&mut reader, &mut output, false); + + assert!(result.is_ok()); + + let output = String::from_utf8(output.into_inner()).unwrap(); + + assert_eq!( + "\ +192.168.0.17\thost.docker.internal +192.168.0.17\tgateway.docker.internal +127.0.0.1\tkubernetes.docker.internal +" + .to_string(), + output + ) + } +}