use crate::result::{BatchError, BatchResult, ConfigError};
use std::env;
use termcolor::{Buffer, ColorChoice, StandardStream, WriteColor};
pub struct Config<W: WriteColor> {
update_mode: Update,
writer: WriterBuilder<W>,
}
impl Config<StandardStream> {
pub fn from_env() -> BatchResult<Self> {
Ok(Self {
update_mode: Update::env()?,
writer: WriterBuilder::default(),
})
}
}
impl<W: WriteColor> Config<W> {
pub fn new(update_mode: Update, writer: WriterBuilder<W>) -> Self {
Self { update_mode, writer }
}
pub fn with_buffer(self) -> Config<Buffer> {
Config {
update_mode: self.update_mode,
writer: WriterBuilder::buffer(),
}
}
pub fn with_stderr_no_color(self) -> Config<StandardStream> {
Config {
update_mode: self.update_mode,
writer: WriterBuilder::no_color(),
}
}
pub fn update_mode(&self) -> Update {
self.update_mode
}
pub fn writer(&self) -> &WriterBuilder<W> {
&self.writer
}
}
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum Update {
Wip,
Overwrite,
}
impl Update {
fn env() -> BatchResult<Self> {
let var = match env::var_os("BATCH_RUN") {
Some(var) => var,
None => return Ok(Update::Wip),
};
match var.as_os_str().to_str() {
Some("wip") => Ok(Update::Wip),
Some("overwrite") => Ok(Update::Overwrite),
_ => Err(BatchError::ConfigError(ConfigError::UpdateEnvVar(var))),
}
}
}
pub struct WriterBuilder<W: WriteColor>(Box<dyn Fn() -> W>);
impl<W: WriteColor> WriterBuilder<W> {
pub fn new<F: Fn() -> W + 'static>(inner: F) -> Self
where
W: 'static,
{
Self(Box::new(inner))
}
pub(crate) fn build(&self) -> W {
self.0()
}
}
impl Default for WriterBuilder<StandardStream> {
fn default() -> Self {
Self(Box::new(|| StandardStream::stderr(ColorChoice::Always)))
}
}
impl WriterBuilder<Buffer> {
pub fn buffer() -> Self {
Self(Box::new(crate::term::buf))
}
}
impl WriterBuilder<StandardStream> {
pub fn no_color() -> Self {
Self(Box::new(|| StandardStream::stderr(ColorChoice::Never)))
}
}