#![allow(
clippy::unreachable, // unreachable added by enum_map::Enum.
clippy::use_self, // False positive on format macro.
clippy::trivial_regex, // Trivial regex added by thiserror::Error.
)]
mod app;
mod io;
mod logging;
mod orient;
pub use logging::LogConfig;
use {
app::Processor,
core::option::Option,
fehler::{throw, throws},
io::{
ConsumeInputError, ConsumeInputIssue, CreateInterfaceError, Interface, ProduceOutputError,
},
log::{error, info},
logging::InitLoggerError,
market::{Consumer, Producer},
structopt::StructOpt,
thiserror::Error as ThisError,
};
#[derive(Clone, Debug, Default, StructOpt)]
pub struct Arguments {
#[structopt(value_name("FILE"))]
file: Option<String>,
#[allow(clippy::missing_docs_in_private_items)] #[structopt(flatten)]
log_config: LogConfig,
}
#[derive(Debug)]
pub struct Paper {
io: Interface,
processor: Processor,
}
impl Paper {
#[inline]
#[throws(CreateError)]
pub fn new(arguments: Arguments) -> Self {
logging::init(arguments.log_config)?;
Self {
io: Interface::new(arguments.file)?,
processor: Processor::new(),
}
}
#[inline]
#[throws(RunError)]
pub fn run(&mut self) {
if let Err(error) = self.execute() {
error!("{}", error);
throw!(error);
}
info!("Application quitting");
}
#[throws(RunError)]
fn execute(&mut self) {
loop {
match self.io.demand() {
Ok(input) => self.io.force_all(self.processor.process(input))?,
Err(issue) => {
if let ConsumeInputIssue::Error(error) = issue {
throw!(error);
}
break;
}
}
}
self.io.join();
}
}
#[derive(Debug, ThisError)]
pub enum Failure {
#[error(transparent)]
Create(#[from] CreateError),
#[error(transparent)]
Run(#[from] RunError),
}
#[derive(Debug, ThisError)]
pub enum CreateError {
#[error("Failed to initialize logger: {0}")]
Logger(#[from] InitLoggerError),
#[error("Failed to create application: {0}")]
Interface(#[from] CreateInterfaceError),
}
#[derive(Debug, ThisError)]
pub enum RunError {
#[error("Failed to consume input: {0}")]
Consume(#[from] ConsumeInputError),
#[error("Failed to produce output: {0}")]
Produce(#[from] ProduceOutputError),
}