#![deny(
clippy::all,
clippy::cargo,
clippy::nursery,
clippy::pedantic,
rust_2018_idioms,
warnings
)]
#![allow(clippy::multiple_crate_versions)]
use serde::{Deserialize, Serialize};
use std::{error, fmt, io, path};
use tempfile::{tempdir, TempDir};
pub trait Processor<'de>: Clone + fmt::Debug + Serialize + Deserialize<'de> {
const NAME: &'static str;
type Error: error::Error;
type Output: fmt::Display;
fn run(&self, context: &Context) -> Result<Option<Self::Output>, Self::Error>;
fn validate(&self) -> Result<(), Self::Error> {
Ok(())
}
}
#[derive(Debug)]
pub struct Context {
workspace: TempDir,
}
impl Context {
pub fn new() -> Result<Self, ContextError> {
Ok(Self {
workspace: tempdir()?,
})
}
pub fn workspace_path(&self) -> &path::Path {
self.workspace.path()
}
}
#[derive(Debug)]
pub enum ContextError {
Io(io::Error),
#[doc(hidden)]
__Unknown, }
impl fmt::Display for ContextError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ContextError::Io(ref err) => write!(f, "IO error: {}", err),
ContextError::__Unknown => unreachable!(),
}
}
}
impl error::Error for ContextError {
fn description(&self) -> &str {
match *self {
ContextError::Io(ref err) => err.description(),
ContextError::__Unknown => unreachable!(),
}
}
fn cause(&self) -> Option<&dyn error::Error> {
match *self {
ContextError::Io(ref err) => Some(err),
ContextError::__Unknown => unreachable!(),
}
}
}
impl From<io::Error> for ContextError {
fn from(err: std::io::Error) -> Self {
ContextError::Io(err)
}
}