I am attempting to write the cat command to learn Rust, but I can\'t seem to convert command line arguments into reader structs.
use std::{env,
The coalesce crate provides a way to do this without boxing and in a way that is less verbose than my other answer. The idea is to use a simple enum that can hold the concrete type corresponding to each arm and a macro (coalesce!) that expands to a match where the body expression is the same for each arm.
#[macro_use]
extern crate coalesce;
use std::io::{self, Read};
use std::fs::File;
use std::path::Path;
use coalesce::Coalesce2;
fn main() {
if let Some(arg) = std::env::args().nth(1).as_ref() {
let reader = match arg.as_ref() {
"-" => Coalesce2::A(io::stdin()),
path => Coalesce2::B(File::open(&Path::new(path)).unwrap()),
};
let reader = coalesce!(2 => |ref reader| reader as &Read);
// the previous line is equivalent to:
let reader = match reader {
Coalesce2::A(ref reader) => reader as &Read,
Coalesce2::B(ref reader) => reader as &Read,
};
}
}