0
votes

Sorry for my noob rust question.

I'm working on a project regarding avro file manipulation tool based on avrow. I see the popular compile error happen on header reading. I see avrow_cli works good but I don't understand why avrow_cli handles that well. Could someone please point out what's wrong? Thank you.

Below is a piece of code and error msg.

use std::env;
use avrow::Header;

fn main() {
    let args: Vec<String> = env::args().collect();

    println!("Hello, {}!", &args[1]);

    let mut file = std::fs::OpenOptions::new()
        .read(true)
        .open(&args[1]);

    let header = Header::from_reader(&mut file);
    println!("{}", header.schema());
}

Compiling avro-dump-schema-rs v0.1.0 (/home/shuduo/work/avro-rs) error[E0277]: the trait bound Result<File, std::io::Error>: std::io::Read is not satisfied --> src/main.rs:13:38 | 13 | let header = Header::from_reader(&mut file); | ^^^^^^^^^ the trait std::io::Read is not implemented for Result<File, std::io::Error> | ::: /home/shuduo/.cargo/registry/src/github.com-1ecc6299db9ec823/avrow-0.2.1/src/reader.rs:638:27 | 638 | pub fn from_reader<R: Read>(reader: &mut R) -> Result<Self, AvrowErr> { | ---- required by this bound in Header::from_reader

error[E0599]: no method named schema found for enum Result<Header, AvrowErr> in the current scope --> src/main.rs:14:27 | 14 | println!("{}", header.schema()); | ^^^^^^ method not found in Result<Header, AvrowErr>

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0599. For more information about an error, try rustc --explain E0277. error: could not compile avro-dump-schema-rs

To learn more, run the command again with --verbose.

1

1 Answers

0
votes

OpenOptions::open() returns a io::Result<File> instead of just File. You have to check if the open() operation was successful before being able to work with the file.

The simplest way to get the file is to call .unwrap() or .expect() on the result, which will cause the application to panic (i.e. crash) in case open() returned an error

 let mut file = std::fs::OpenOptions::new()
        .read(true)
        .open(&args[1])
        .expect(&format!("Failed to open {}", args[1]));

Or you can try to gracefully handle the error:

let result = std::fs::OpenOptions::new()
        .read(true)
        .open(&args[1]);

    // you can use `match` to extract the OK/Err cases
    match result{
        Ok(mut file) => {
            let header = Header::from_reader(&mut file);
            println!("{}", header.schema());
        }

        Err(e) => {
            // handle the error
        }
    }

    // or you can use `if let` if you are interested only in one of the enum variants (OK or Err)
    if let Ok(file) = result{
        let header = Header::from_reader(&mut file);
        println!("{}", header.schema());
    }
   

The same is valid for your second error message - from_reader() returns a Result which you should handle.