Reputation: 326
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
Upvotes: 2
Views: 2074
Reputation: 326
thanks @PeterHall, that Read trait thing lighted bulb on, I didn't realized that I could pass stdin to BufReader, so that does the trick:
let stdin = io::stdin();
for line in BufReader::new(stdin).lines() {
...
the same way that one does:
let f = File::open(file)?;
for line in BufReader::new(f).lines() {
This is what a I was looking for.
Thanks a mil
Upvotes: 5