skip until matching lines seen
This commit is contained in:
parent
47acf65bf7
commit
c1fdfbdcc8
2 changed files with 73 additions and 13 deletions
82
src/lib.rs
82
src/lib.rs
|
@ -22,23 +22,69 @@ pub struct Cli {
|
||||||
ignore_extras: bool,
|
ignore_extras: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn skip<F>(cli: Cli, mut out: F) -> io::Result<()>
|
pub fn skip<F>(cli: &Cli, mut out: F) -> io::Result<()>
|
||||||
where F: FnMut(String) -> ()
|
where F: FnMut(String) -> ()
|
||||||
{
|
{
|
||||||
match &cli.file {
|
match &cli.file {
|
||||||
Some(file) => {
|
Some(ref file) => {
|
||||||
let content = fs::read_to_string(file).expect("Could not read file");
|
if let Some(line) = &cli.line {
|
||||||
let mut counter = 0usize;
|
skip_file_lines_matching(&cli, out, file, line)
|
||||||
for current_line in content.lines() {
|
} else if let Some(ref token) = cli.token {
|
||||||
counter += 1;
|
skip_file_tokens(cli, out, file, token)
|
||||||
if counter > cli.lines {
|
} else {
|
||||||
out(String::from(current_line));
|
skip_file_lines(cli, out, file)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => todo!("reading from stdin")
|
None => todo!("reading from stdin")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_file_lines<F>(cli: &Cli, mut out: F, file: &PathBuf) -> io::Result<()>
|
||||||
|
where F: FnMut(String) -> ()
|
||||||
|
{
|
||||||
|
eprintln!("skip_file_lines");
|
||||||
|
let content = fs::read_to_string(file).expect("Could not read file");
|
||||||
|
let mut counter = 0usize;
|
||||||
|
for current_line in content.lines() {
|
||||||
|
if counter >= cli.lines {
|
||||||
|
out(String::from(current_line));
|
||||||
|
}
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_file_lines_matching<F>(cli: &Cli, mut out: F, file: &PathBuf, line: &str) -> io::Result<()>
|
||||||
|
where F: FnMut(String) -> ()
|
||||||
|
{
|
||||||
|
eprintln!("skip_file_lines_matching");
|
||||||
|
let content = fs::read_to_string(file).expect("Could not read file");
|
||||||
|
let mut counter = 0usize;
|
||||||
|
for current_line in content.lines() {
|
||||||
|
if counter >= cli.lines {
|
||||||
|
out(String::from(current_line));
|
||||||
|
}
|
||||||
|
if line == current_line {
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_file_tokens<F>(cli: &Cli, mut out: F, file: &PathBuf, token: &str) -> io::Result<()>
|
||||||
|
where F: FnMut(String) -> ()
|
||||||
|
{
|
||||||
|
eprintln!("skip_file_lines_tokens");
|
||||||
|
let content = fs::read_to_string(file).expect("Could not read file");
|
||||||
|
let mut counter = 0usize;
|
||||||
|
for current_line in content.lines() {
|
||||||
|
if counter >= cli.lines {
|
||||||
|
out(String::from(current_line));
|
||||||
|
}
|
||||||
|
if current_line.contains(&token) {
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +100,7 @@ mod tests {
|
||||||
let mut lines: Vec<String> = Vec::new();
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
//when
|
//when
|
||||||
skip(cli, |line| lines.push(line))?;
|
skip(&cli, |line| lines.push(line))?;
|
||||||
|
|
||||||
//then
|
//then
|
||||||
assert_eq!(lines, vec!["line 2"]);
|
assert_eq!(lines, vec!["line 2"]);
|
||||||
|
@ -68,11 +114,25 @@ mod tests {
|
||||||
let mut lines: Vec<String> = Vec::new();
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
//when
|
//when
|
||||||
skip(cli, |line| lines.push(line))?;
|
skip(&cli, |line| lines.push(line))?;
|
||||||
|
|
||||||
//then
|
//then
|
||||||
assert_eq!(lines, vec!["alpha", "gamma"]);
|
assert_eq!(lines, vec!["alpha", "gamma"]);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn skip_two_matching_lines_of_alpha() -> io::Result<()> {
|
||||||
|
//given
|
||||||
|
let cli = Cli { lines: 2, file: Some(PathBuf::from("tests/four-lines.txt")), line: Some(String::from("alpha")), token: None, ignore_extras: false };
|
||||||
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
//when
|
||||||
|
skip(&cli, |line| lines.push(line))?;
|
||||||
|
|
||||||
|
//then
|
||||||
|
assert_eq!(lines, vec!["gamma"]);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ use clap::Parser;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
let args = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let stdout = std::io::stdout();
|
let stdout = std::io::stdout();
|
||||||
let mut output = stdout.lock();
|
let mut output = stdout.lock();
|
||||||
|
|
||||||
skip(args, |line| {
|
skip(&cli, |line| {
|
||||||
match writeln!(output, "{}", line) {
|
match writeln!(output, "{}", line) {
|
||||||
Err(_) => (),
|
Err(_) => (),
|
||||||
Ok(_) => ()
|
Ok(_) => ()
|
||||||
|
|
Loading…
Reference in a new issue