As a newbie on rust i wonder to know if there is way to use a single function/macro/anything-else to read a line from a passed file or from stdin, passing as argument a kind of buffer reader maybe?
I haven't found anything that help yet, the following code works fine, once I was able to wrap some validations on a macro I know that code can be improved. I'm open for suggestion about how to improve that macro indeed
... macro_rules! validate { ($line:expr, $blank:expr, $squeeze:expr, $line_count:expr, $show_number:expr) => { if $line.len() <= 0 { $blank +=1; } else{ $blank = 0; } if $squeeze & ($blank > 1) { continue; } if $show_number { $line_count += 1; } } } ... for file in opt.files { blank_line_count = 0; line_count = 0; if file.to_str() != Some("-") { let f = File::open(file)?; for line in BufReader::new(f).lines() { let l = line.unwrap(); validate!(l, blank_line_count, opt.squeeze_blank, line_count, opt.number); // will continue the loop if not valid println!("{}", format_line(l, opt.show_ends, opt.show_tabs, opt.show_nonprinting, line_count)); // will be skipped if not valid } } else { let stdin = io::stdin(); let mut bytes_read: usize; loop { let mut line = String::new(); bytes_read = stdin.lock().read_line(&mut line).expect("Could not read line"); if bytes_read == 0 { break; } line.pop(); validate!(line, blank_line_count, opt.squeeze_blank, line_count, opt.number);// will continue the loop if not valid println!("{}", format_line(line, opt.show_ends, opt.show_tabs, opt.show_nonprinting, line_count)); // will be skipped if not valid } } } .... As shown File and stdin have different treatments, but they both basically do the same thing, run through a loop looking for a valid entry
read_linemethod you are calling on the result ofstdin.lock()and thelines()method you are calling on theBufReader::new(f)are from the sameBufRead. So you are already using the trait you are looking for!Read, butBufRead, because lines are wanted.