How to pass BufReader to another function in rust?

Viewed 796

new to rust, I'm asking this to hopefully understand how to work with the language better..

Heres me trying to read a file, pass the file handle to a different function and print the lines from there:

use std::fs::File;
use std::io::{self, BufReader};
use std::io::BufRead;
use async_std::task;

async fn scrape<R: BufRead>(reader: &mut R) {
    reader.lines().for_each(|line| println!(line));
}

fn main() -> io::Result<()> {
    let file = File::open("wlist.txt")?;
    let reader = BufReader::new(file);

    // print_type_of(&reader); // prints std::io::buffered::BufReader<std::fs::File>
    task::block_on(scrape(&mut reader));

    Ok(())
}

// helper functions
fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

Would love some insights regarding what concepts i'm missing and how this should be done properly !

1 Answers

This version atleast compiles, but there's no async in the playground so I coudn't add async.

You have to catch errors in scrape by using try_for_each function, inside you parse io::Result<String> via and_then. In your main you have to catch all errors explicitly, not allowed to let io::Error slip through ? operator

use std::fs::File;
use std::io::{self, BufReader};
use std::io::BufRead;
//use async_std::task;

fn scrape<R: BufRead>(reader: &mut R) -> io::Result<()> {
    reader.lines()
        .try_for_each(|lineResult| lineResult.and_then(|line| Ok(println!("{}", line))))?;
    Ok(())
}

fn main() {
    //let fileResult = File::open("wlist.txt");
    //let mut file;
    //match fileResult {
    //    Ok(f) => file = f,
    //    Err(e) => println!("File open error! {}", e),
    //}
    let mut file = b"hello\nworld\nhow\nare\nyou\ndoing" as &[u8]; // no file in playground, so just a buffer
    let mut reader = BufReader::new(file);

    // print_type_of(&reader); // prints std::io::buffered::BufReader<std::fs::File>
    match scrape(&mut reader) {
        Ok(_) => println!("Scraping is done!"),
        Err(e) => println!("File read error! {}", e),
    }
}

// helper functions
fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}
Related