use super::Parts;
use super::{IntoJobResultParts, JobResultParts, Void};
use crate::JobResult;
use crate::error::{BoxError, Error};
use crate::metadata::{MetadataMap, MetadataValue};
use alloc::boxed::Box;
use alloc::string::String;
use alloc::{borrow::Cow, vec::Vec};
use bytes::{Bytes, BytesMut};
use core::convert::Infallible;
pub trait IntoJobResult {
#[must_use]
fn into_job_result(self) -> Option<JobResult>;
}
impl IntoJobResult for Void {
fn into_job_result(self) -> Option<JobResult> {
None
}
}
impl IntoJobResult for () {
fn into_job_result(self) -> Option<JobResult> {
Bytes::new().into_job_result()
}
}
impl IntoJobResult for Infallible {
fn into_job_result(self) -> Option<JobResult> {
match self {}
}
}
impl<T> IntoJobResult for Option<T>
where
T: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
self.and_then(IntoJobResult::into_job_result)
}
}
impl<T, E> IntoJobResult for Result<T, E>
where
T: IntoJobResult,
E: Into<BoxError>,
{
fn into_job_result(self) -> Option<JobResult> {
match self {
Ok(value) => value.into_job_result(),
Err(err) => Some(JobResult::Err(Error::new(err))),
}
}
}
impl<B> IntoJobResult for super::JobResult<B>
where
B: Into<Bytes> + Send + 'static,
{
fn into_job_result(self) -> Option<JobResult> {
Some(self.map(Into::into))
}
}
impl IntoJobResult for Parts {
fn into_job_result(self) -> Option<JobResult> {
Some(JobResult::from_parts(self, Bytes::new()))
}
}
impl IntoJobResult for Bytes {
fn into_job_result(self) -> Option<JobResult> {
Some(JobResult::new(self))
}
}
impl IntoJobResult for &'static str {
fn into_job_result(self) -> Option<JobResult> {
Cow::Borrowed(self).into_job_result()
}
}
impl IntoJobResult for String {
fn into_job_result(self) -> Option<JobResult> {
Cow::<'static, str>::Owned(self).into_job_result()
}
}
impl IntoJobResult for Box<str> {
fn into_job_result(self) -> Option<JobResult> {
String::from(self).into_job_result()
}
}
impl IntoJobResult for Cow<'static, str> {
fn into_job_result(self) -> Option<JobResult> {
Bytes::from(self.into_owned()).into_job_result()
}
}
impl IntoJobResult for BytesMut {
fn into_job_result(self) -> Option<JobResult> {
self.freeze().into_job_result()
}
}
impl IntoJobResult for &'static [u8] {
fn into_job_result(self) -> Option<JobResult> {
Cow::Borrowed(self).into_job_result()
}
}
impl<const N: usize> IntoJobResult for &'static [u8; N] {
fn into_job_result(self) -> Option<JobResult> {
self.as_slice().into_job_result()
}
}
impl<const N: usize> IntoJobResult for [u8; N] {
fn into_job_result(self) -> Option<JobResult> {
self.to_vec().into_job_result()
}
}
impl IntoJobResult for Vec<u8> {
fn into_job_result(self) -> Option<JobResult> {
Cow::<'static, [u8]>::Owned(self).into_job_result()
}
}
impl IntoJobResult for Box<[u8]> {
fn into_job_result(self) -> Option<JobResult> {
Vec::from(self).into_job_result()
}
}
impl IntoJobResult for Cow<'static, [u8]> {
fn into_job_result(self) -> Option<JobResult> {
Bytes::from(self.into_owned()).into_job_result()
}
}
impl IntoJobResult for MetadataMap<MetadataValue> {
fn into_job_result(self) -> Option<JobResult> {
let mut res = ().into_job_result()?;
if let Some(metadata) = res.metadata_mut() {
*metadata = self;
}
Some(res)
}
}
impl<K, V, const N: usize> IntoJobResult for [(K, V); N]
where
K: TryInto<&'static str>,
K::Error: core::error::Error + Send + Sync + Into<BoxError> + 'static,
V: TryInto<MetadataValue>,
V::Error: core::error::Error + Send + Sync + Into<BoxError> + 'static,
{
fn into_job_result(self) -> Option<JobResult> {
(self, ()).into_job_result()
}
}
impl<R> IntoJobResult for (Parts, R)
where
R: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
let (parts, res) = self;
let mut org = res.into_job_result()?;
if let Some(metadata) = org.metadata_mut() {
metadata.extend(parts.metadata);
}
Some(org)
}
}
impl<R> IntoJobResult for (super::JobResult<()>, R)
where
R: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
let (template, res) = self;
match template.into_parts() {
Ok((parts, ())) => (parts, res).into_job_result(),
Err(e) => Some(JobResult::Err(e)),
}
}
}
impl<R> IntoJobResult for (R,)
where
R: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
let (res,) = self;
res.into_job_result()
}
}
macro_rules! impl_into_job_result {
( $($ty:ident),* $(,)? ) => {
#[allow(non_snake_case)]
impl<R, $($ty,)*> IntoJobResult for ($($ty),*, R)
where
$( $ty: IntoJobResultParts, )*
R: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
let ($($ty),*, res) = self;
let res = res.into_job_result()?;
let parts = JobResultParts { res };
$(
let parts = match $ty.into_job_result_parts(parts) {
Ok(parts) => parts,
Err(err) => {
return Some(JobResult::Err(Error::new(err)));
}
};
)*
Some(parts.res)
}
}
#[allow(non_snake_case)]
impl<R, $($ty,)*> IntoJobResult for (crate::job::result::Parts, $($ty),*, R)
where
$( $ty: IntoJobResultParts, )*
R: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
let (outer_parts, $($ty),*, res) = self;
let res = res.into_job_result()?;
let parts = JobResultParts { res };
$(
let parts = match $ty.into_job_result_parts(parts) {
Ok(parts) => parts,
Err(err) => {
return Some(JobResult::Err(Error::new(err)));
}
};
)*
(outer_parts, parts.res).into_job_result()
}
}
#[allow(non_snake_case)]
impl<R, $($ty,)*> IntoJobResult for (crate::job::result::JobResult<()>, $($ty),*, R)
where
$( $ty: IntoJobResultParts, )*
R: IntoJobResult,
{
fn into_job_result(self) -> Option<JobResult> {
let (template, $($ty),*, res) = self;
match template.into_parts() {
Ok((parts, ())) => {
(parts, $($ty),*, res).into_job_result()
},
Err(err) => Some(JobResult::Err(Error::new(err)))
}
}
}
}
}
all_the_tuples_no_last_special_case!(impl_into_job_result);