use std::io::{stdin, stdout, Write, BufReader, BufRead};
use std::fs::{File};
use std::path::{Path};
const OBJECT_IN_FILE_NUMBER: i32 = 3;
const OBJECT_OUT_FILE_NUMBER: i32 = 4;
const OBJECT_ERR_FILE_NUMBER: i32 = 5;
pub trait ObjectRead<T> {
fn read(&mut self) -> std::io::Result<T>;
}
pub trait ObjectWrite<T> {
fn write(&mut self, object: T) -> std::io::Result<()>;
fn flush(&mut self) -> std::io::Result<()>;
}
pub enum Input {
Stdin {
prompt: String,
},
Script {
file: BufReader<File>,
}
}
impl Input {
pub fn from_stdin() -> Self { Self::Stdin { prompt: ">".to_string() } }
pub fn from_script_file(path: &Path) -> std::io::Result<Self> {
let file = BufReader::new(File::open(path)?);
return Ok(Self::Script { file });
}
pub fn is_stdin(&self) -> bool {
match self {
Self::Stdin {..} => true,
_ => false,
}
}
pub fn is_script(&self) -> bool { !self.is_stdin() }
pub fn read_line(&mut self, mut input_line: &mut String) -> std::io::Result<usize> {
match self {
Self::Stdin { prompt } => {
if atty::is(atty::Stream::Stdin) {
let stdout = stdout();
let mut stdout = stdout.lock();
write!(stdout, "{} ", prompt)?;
stdout.flush()?;
}
return stdin().read_line(&mut input_line);
}
Self::Script { file } => {
return file.read_line(&mut input_line);
}
}
}
}