use std::{fs, io};
use std::io::{Cursor, Error, Read, Write};
pub enum Input {
Standard(io::Stdin),
Memory(io::Cursor<Vec<u8>>),
File(fs::File),
}
pub enum Output {
Standard(io::Stdout),
Memory(io::Cursor<Vec<u8>>),
File(fs::File),
}
pub enum InputOutput {
Standard(io::Stdin, io::Stdout),
Memory(io::Cursor<Vec<u8>>),
File(fs::File),
}
impl Input {
pub fn stdin() -> Self {
Input::Standard(io::stdin())
}
pub fn memory() -> Self {
Input::Memory(Cursor::new(vec![]))
}
pub fn file(path: &str) -> io::Result<Self> {
fs::OpenOptions::new()
.read(true)
.open(path)
.map(Input::File)
}
pub fn from_arg(arg: Option<&str>) -> io::Result<Self> {
match arg {
None | Some("-") => Ok(Self::stdin()),
Some(fname) => Self::file(fname),
}
}
}
impl Read for Input {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self {
Input::Standard(ref mut s) => s.read(buf),
Input::Memory(ref mut m) => m.read(buf),
Input::File(ref mut f) => f.read(buf),
}
}
}
impl Output {
pub fn stdout() -> Self {
Output::Standard(io::stdout())
}
pub fn memory() -> Self {
Output::Memory(Cursor::new(vec![]))
}
pub fn file(path: &str) -> io::Result<Self> {
fs::OpenOptions::new()
.write(true)
.create(true)
.open(path)
.map(Output::File)
}
pub fn from_arg(arg: Option<&str>) -> io::Result<Self> {
match arg {
None | Some("-") => Ok(Self::stdout()),
Some(fname) => Self::file(fname),
}
}
}
impl Write for Output {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self {
Output::Standard(ref mut s) => s.write(buf),
Output::Memory(ref mut m) => m.write(buf),
Output::File(ref mut f) => f.write(buf),
}
}
fn flush(&mut self) -> Result<(), Error> {
match self {
Output::Standard(ref mut s) => s.flush(),
Output::Memory(ref mut m) => m.flush(),
Output::File(ref mut f) => f.flush(),
}
}
}
impl InputOutput {
pub fn stdio() -> InputOutput {
InputOutput::Standard(io::stdin(), io::stdout())
}
pub fn memory() -> InputOutput {
InputOutput::Memory(Cursor::new(vec![]))
}
pub fn file(path: &str) -> io::Result<InputOutput> {
fs::OpenOptions::new().read(true).write(true).open(path).map(InputOutput::File)
}
pub fn from_arg(arg: Option<&str>) -> io::Result<InputOutput> {
match arg {
None | Some("-") => Ok(Self::stdio()),
Some(path) => Self::file(path),
}
}
}
impl Read for InputOutput {
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
match self {
InputOutput::Standard(stdin, _) => stdin.read(buf),
InputOutput::Memory(c) => c.read(buf),
InputOutput::File(f) => f.read(buf)
}
}
}
impl Write for InputOutput {
fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
match self {
InputOutput::Standard(_, stdout) => stdout.write(buf),
InputOutput::Memory(c) => c.write(buf),
InputOutput::File(f) => f.write(buf),
}
}
fn flush(&mut self) -> Result<(), Error> {
match self {
InputOutput::Standard(_, stdout) => stdout.flush(),
InputOutput::Memory(m) => m.flush(),
InputOutput::File(f) => f.flush()
}
}
}