I'm trying to type-pun an io::stdio instance and a BufReader wrapping a file so that I can write code assuming a buffered input source. I've tried several variations of trying to cast an io::stdio() to a BufRead type and all have failed with one or more variations of:
error: mismatched types: expected `std::io::stdio::StdinLock<'_>`, found `std::io::buffered::BufReader<std::fs::File>` (expected struct `std::io::stdio::StdinLock`, found struct `std::io::buffered::BufReader`) [E0308] csv_to_json.rs:26 reader = BufReader::new(file.unwrap()); Here's the code:
use std::io; use std::io::BufReader; use std::io::prelude::*; use std::env; use std::process::exit; use std::fs::File; fn usage() { println!("Usage: cat input.csv | csv_to_json"); } fn main() { let stdin = io::stdin(); let mut reader = stdin.lock(); // Assignment. (1) let args: Vec<String> = env::args().collect(); if args.len() > 1 { usage(); exit(1); } else if args.len() == 1 { let file = File::open(args[0].clone()); if !file.is_ok() { usage(); exit(1); } reader = BufReader::new(file.unwrap()); // Reassignment. This is the line that fails. } // Rest of the code works with reader assuming a buffered input source. } Things that I have tried:
let mut reader : BufRead = io::stdin(); // Fails. let mut reader : BufReader<Read> = io::stdin(); // Fails. let mut reader : BufReader<_> = io::stdin(); // Fails let mut reader : BufRead = io::stdin().lock(); // Fails later. let mut reader = BufReader::new(io::stdin()); // Fails with type mismatch. let mut reader = BufReader::new(io::stdin().lock()); // Fails with type mismatch. I've even tried extracting that code to its own function and the return type signature fails with similar error conditions. How can I create a "reader" variable that's either a BufferedReader over stdio or a BufferedReader over a File without facing type errors everywhere?