我知道,你說你想要的東西更優雅和不枚舉,但我認爲枚舉的解決方案是相當優雅。所以這裏有一個嘗試:
use std::fs;
use std::io::{self, Read, Seek, SeekFrom};
enum Input {
File(fs::File),
Stdin(io::Stdin),
}
impl Read for Input {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match *self {
Input::File(ref mut file) => file.read(buf),
Input::Stdin(ref mut stdin) => stdin.read(buf),
}
}
}
impl Seek for Input {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
match *self {
Input::File(ref mut file) => file.seek(pos),
Input::Stdin(_) => {
Err(io::Error::new(
io::ErrorKind::Other,
"not supported by stdin-input",
))
},
}
}
}
把這樣的代碼放在你的一些子模塊中,不要再擔心它了。您可以使用Input
類型的對象,就像您使用File
一樣:無論如何,您必須處理查找錯誤,因此處理無法通過stdin查找應該非常容易。舉例:
let arg = std::env::args().nth(1).unwrap();
let mut input = if arg == "--" {
Input::Stdin(io::stdin())
} else {
Input::File(fs::File::open(&arg).expect("I should handle that.."))
};
let mut v = Vec::new();
let _idc = input.read_to_end(&mut v);
match input.seek(SeekFrom::End(0)) {
Err(_) => println!("oh noes :("),
Ok(bytes) => println!("yeah, input is {} long", bytes),
}
你需要什麼操作來「查找」輸入?如果你真的需要一個任意的「seek」,唯一的希望就是將整個stdin讀入一個'Cursor>'。 –
kennytm
你顯然不需要**來尋求你是否可以處理來自stdin的閱讀。 – Shepmaster