use std::{fmt::Debug, sync::Arc};
use crate::{
error::{BoxDynError, Error},
task::{attempt::Attempt, task_id::TaskId},
};
#[derive(Debug, Clone)]
pub struct Response<Res> {
pub inner: Result<Res, Error>,
pub task_id: TaskId,
pub attempt: Attempt,
pub(crate) _priv: (),
}
impl<Res> Response<Res> {
pub fn new(inner: Result<Res, Error>, task_id: TaskId, attempt: Attempt) -> Self {
Response {
inner,
task_id,
attempt,
_priv: (),
}
}
pub fn success(res: Res, task_id: TaskId, attempt: Attempt) -> Self {
Self::new(Ok(res), task_id, attempt)
}
pub fn failure(error: Error, task_id: TaskId, attempt: Attempt) -> Self {
Self::new(Err(error), task_id, attempt)
}
pub fn is_success(&self) -> bool {
self.inner.is_ok()
}
pub fn is_failure(&self) -> bool {
self.inner.is_err()
}
pub fn map<F, T>(&self, f: F) -> Response<T>
where
F: FnOnce(&Res) -> T,
{
Response {
inner: self.inner.as_ref().map(f).map_err(|e| e.clone()),
task_id: self.task_id.clone(),
attempt: self.attempt.clone(),
_priv: (),
}
}
}
pub trait IntoResponse {
type Result;
fn into_response(self) -> Self::Result;
}
impl IntoResponse for bool {
type Result = std::result::Result<Self, Error>;
fn into_response(self) -> std::result::Result<Self, Error> {
match self {
true => Ok(true),
false => Err(Error::Failed(Arc::new(Box::new(std::io::Error::new(
std::io::ErrorKind::Other,
"Job returned false",
))))),
}
}
}
impl<T, E: Into<BoxDynError>> IntoResponse for std::result::Result<T, E> {
type Result = Result<T, Error>;
fn into_response(self) -> Result<T, Error> {
match self {
Ok(value) => Ok(value),
Err(e) => {
let e = e.into();
if let Some(custom_error) = e.downcast_ref::<Error>() {
return Err(custom_error.clone());
}
Err(Error::Failed(Arc::new(e)))
}
}
}
}
macro_rules! SIMPLE_JOB_RESULT {
($type:ty) => {
impl IntoResponse for $type {
type Result = std::result::Result<$type, Error>;
fn into_response(self) -> std::result::Result<$type, Error> {
Ok(self)
}
}
};
}
SIMPLE_JOB_RESULT!(());
SIMPLE_JOB_RESULT!(u8);
SIMPLE_JOB_RESULT!(u16);
SIMPLE_JOB_RESULT!(u32);
SIMPLE_JOB_RESULT!(u64);
SIMPLE_JOB_RESULT!(usize);
SIMPLE_JOB_RESULT!(i8);
SIMPLE_JOB_RESULT!(i16);
SIMPLE_JOB_RESULT!(i32);
SIMPLE_JOB_RESULT!(i64);
SIMPLE_JOB_RESULT!(isize);
SIMPLE_JOB_RESULT!(f32);
SIMPLE_JOB_RESULT!(f64);
SIMPLE_JOB_RESULT!(String);
SIMPLE_JOB_RESULT!(&'static str);