Select by arguments

I am trying to write a program that takes input from a file or standard in, depending on whether the command line argument is passed. For this, I use getopts, which allows you to get a value Option<String>with an argument value. If the value Some(filename), I want to open this file and create a buffered reader above it. If it is None, I want to set the stream to stdin.

let input: Box<Read> = match matches.opt_str("i") {
    Some(ifname) => Box::new(BufReader::new(File::open(ifname).unwrap())),
    None => Box::new(io::stdin()),
};

Thus, the input type to be &reador Box<Read>have been Stdin, and BufReaderare incompatible types. Obviously, it &readwill not work, since there is no variable that actually owns the object, which remains in the scope for a long time. So I tried to use it Box<Read>, but it still gives me the error oh input, not for long enough.

What will be the rust (rusty? Rustic?) Way to do something like this?

MCVE:

use std::io;
use std::borrow::BorrowMut;
use std::io::{BufReader,BufWriter,Read,Write};
use std::fs::File;

fn rc4(key: &[u8], input: &mut Read, output: &mut Write) {
    // Read and write here                                                                                                                                                                           
}

fn main() {
    let mut input: Box<Read> = match Some("file-from-parser.txt") {
        Some(ifname) => Box::new(BufReader::new(File::open(ifname).unwrap())),
        None => Box::new(io::stdin()),
    };

    rc4(&[1u8, 2, 3], input.borrow_mut(), &mut io::stdout());
}
+4
source share
1 answer

The following code works:

use std::io;
use std::io::{BufReader, Read, Write};
use std::fs::File;

fn rc4(key: &[u8], input: &mut Read, output: &mut Write) {
    // Read and write here                                                                                                                                                                           
}

fn main() {
    let mut input: Box<Read> = match Some("file-from-parser.txt") {
        Some(ifname) => Box::new(BufReader::new(File::open(ifname).unwrap())),
        None => Box::new(io::stdin()),
    };

    rc4(&[1u8, 2, 3], &mut input, &mut io::stdout());
}

, borrow_mut(), Box , . , , rc4 :

fn rc4<R: Read, W: Write>(key: &[u8], input: &mut R, output: &mut W)

fn rc4<R: Read, W: Write>(key: &[u8], input: R, output: W)

( , &mut R Read, R - Read, Write; , , mut input: R / mut output: W API, )

.

, borrow_mut() , . , . , - , Box<Read> - -.

, Box :

fn main() {
    let mut i1;
    let mut i2;
    let mut input: &mut Read = match Some("file-from-parser.txt") {
        Some(ifname) => {
            i1 = BufReader::new(File::open(ifname).unwrap());
            &mut i1
        }
        None => {
            i2 = io::stdin();
            &mut i2
        }
    };

    rc4(&[1, 2, 3], input, &mut io::stdout());
}

.

+4

Source: https://habr.com/ru/post/1610540/


All Articles