use std::{ error::Error as StdError, io::{Error as IoError, ErrorKind}, ops::{Deref, DerefMut}, }; #[derive(Debug)] pub struct Error where TErrorData: Default, { error: Box, status: Option, body: Option>, data: TErrorData, } impl Error where TErrorData: Default, { pub fn new(error: Box) -> Self { Error { body: None, status: None, error, data: TErrorData::default(), } } pub fn new_with_data( error: Box, data: TErrorData, ) -> Self { Error { error, body: None, status: None, data, } } pub fn empty() -> Self { Error { body: None, status: None, error: Box::new(IoError::from(ErrorKind::NotFound)), data: TErrorData::default(), } } pub fn as_result() -> Result { Err(Error::empty()) } pub fn get_status(&self) -> Option { self.status } pub fn status(mut self, status: u16) -> Self { self.status = Some(status); self } pub fn body(mut self, body: TBody) -> Self where TBody: AsRef, { self.body = Some(body.as_ref().as_bytes().to_vec()); self } pub fn get_body_bytes(&self) -> Option<&[u8]> { self.body.as_ref().map(AsRef::as_ref) } pub fn body_bytes(mut self, bytes: &[u8]) -> Self { self.body = Some(bytes.to_vec()); self } pub fn get_error(&self) -> &(dyn StdError + Send + Sync) { self.error.as_ref() } pub fn error(mut self, error: Box) -> Self { self.error = error; self } pub fn get_data(&self) -> &TErrorData { &self.data } pub fn get_data_mut(&mut self) -> &mut TErrorData { &mut self.data } pub fn data(mut self, data: TErrorData) -> Self { self.data = data; self } } impl AsRef for Error where TErrorData: Default + Send + Sync, { fn as_ref(&self) -> &TErrorData { self.get_data() } } impl AsMut for Error where TErrorData: Default + Send + Sync, { fn as_mut(&mut self) -> &mut TErrorData { self.get_data_mut() } } impl Deref for Error where TErrorData: Default + Send + Sync, { type Target = TErrorData; fn deref(&self) -> &TErrorData { self.get_data() } } impl DerefMut for Error where TErrorData: Default + Send + Sync, { fn deref_mut(&mut self) -> &mut TErrorData { self.get_data_mut() } } impl From for Error where StdErr: 'static + StdError + Send + Sync, TErrorData: Default + Send + Sync, { fn from(err: StdErr) -> Self { Self::new_with_data(Box::new(err), Default::default()) } } pub trait AsError where Value: Send + Sync, TErrorData: Default + Send + Sync, { fn status(self, status: u16) -> Result>; fn body_bytes(self, body: &[u8]) -> Result>; fn body(self, body: TBody) -> Result> where TBody: AsRef; } impl AsError for Result where StdErr: 'static + StdError + Send + Sync, Value: Send + Sync, TErrorData: Default + Send + Sync, { fn status(self, status: u16) -> Result> { match self { Ok(value) => Ok(value), Err(err) => { Err(Error::new_with_data(Box::new(err), TErrorData::default()) .status(status)) } } } fn body_bytes(self, body: &[u8]) -> Result> { match self { Ok(value) => Ok(value), Err(err) => { Err(Error::new_with_data(Box::new(err), TErrorData::default()) .body_bytes(body)) } } } fn body(self, body: TBody) -> Result> where TBody: AsRef, { match self { Ok(value) => Ok(value), Err(err) => { Err(Error::new_with_data(Box::new(err), TErrorData::default()) .body(body.as_ref())) } } } } impl AsError for Result> where Value: Send + Sync, TErrorData: Default + Send + Sync, { fn status(self, status: u16) -> Result> { match self { Ok(value) => Ok(value), Err(err) => Err(err.status(status)), } } fn body_bytes(self, body: &[u8]) -> Result> { match self { Ok(value) => Ok(value), Err(err) => Err(err.body_bytes(body)), } } fn body(self, body: TBody) -> Result> where TBody: AsRef, { match self { Ok(value) => Ok(value), Err(err) => Err(err.body(body.as_ref())), } } } impl AsError for Option where Value: Send + Sync, TErrorData: Default + Send + Sync, { fn status(self, status: u16) -> Result> { match self { Some(value) => Ok(value), None => Err(Error::new_with_data( Box::new(IoError::from(ErrorKind::NotFound)), TErrorData::default(), ) .status(status)), } } fn body_bytes(self, body: &[u8]) -> Result> { match self { Some(value) => Ok(value), None => Err(Error::new_with_data( Box::new(IoError::from(ErrorKind::NotFound)), TErrorData::default(), ) .body_bytes(body)), } } fn body(self, body: TBody) -> Result> where TBody: AsRef, { match self { Some(value) => Ok(value), None => Err(Error::new_with_data( Box::new(IoError::from(ErrorKind::NotFound)), TErrorData::default(), ) .body(body.as_ref())), } } } pub type DefaultError = Error<()>;