jeudi 6 janvier 2022

How do I assign either BufWriter

I'm trying to create a Writer instance either from standard output or from a file freshly created (if a path is provided), then use that instance to write to it.

The problem is that I'm unable to assign it using a match expression:

let file;
let stdout = stdout().lock();

// argpath, when not None, contains some path to a file to create 
let mut writer = match argpath {
    Some(path) => {
        file = File::create(path)?;
        BufWriter::new(file)
    },
    None => {
        BufWriter::new(stdout)
    }
};

writeln!(writer, "Blah");

The compiler complains obviously, as the two arms of the match do not return the same object, BufWriter<File> and BufWriter<StdoutLock>:

error[E0308]: `match` arms have incompatible types
   --> src/main.rs:115:13
    |
109 |       let mut writer = match argpath {
    |  ______________________-
110 | |         Some(path) => {
111 | |             file = File::create(path)?;
112 | |             BufWriter::new(file)
    | |             -------------------- this is found to be of type `std::io::BufWriter<File>`
...   |
115 | |             BufWriter::new(stdout)
    | |             ^^^^^^^^^^^^^^^^^^^^^^ expected struct `File`, found struct `StdoutLock`
116 | |         }
117 | |     };
    | |_____- `match` arms have incompatible types
    |
    = note: expected type `std::io::BufWriter<File>`
             found struct `std::io::BufWriter<StdoutLock<'_>>`
note: return type inferred to be `std::io::BufWriter<File>` here

In general, is there an existing programming pattern, in Rust, that allows to assign a BufWriter<> to a variable, irrespective of the inner type, so the following code can consume it as a regular object implementing the Write traits?

Aucun commentaire:

Enregistrer un commentaire