use futures_util::{Stream, TryStreamExt};
use rspc_procedure::{ProcedureError, ProcedureStream};
use serde::Serialize;
use specta::{datatype::DataType, Generics, Type, TypeCollection};
use crate::Error;
pub trait ResolverOutput<TError>: Sized + Send + 'static {
type T;
fn data_type(types: &mut TypeCollection) -> DataType;
fn into_stream(self) -> impl Stream<Item = Result<Self::T, ProcedureError>> + Send + 'static;
fn into_procedure_stream(
stream: impl Stream<Item = Result<Self::T, ProcedureError>> + Send + 'static,
) -> ProcedureStream;
}
impl<T, E> ResolverOutput<E> for T
where
T: Serialize + Type + Send + Sync + 'static,
E: Error,
{
type T = T;
fn data_type(types: &mut TypeCollection) -> DataType {
T::inline(types, Generics::Definition)
}
fn into_stream(self) -> impl Stream<Item = Result<Self::T, ProcedureError>> + Send + 'static {
futures_util::stream::once(async move { Ok(self) })
}
fn into_procedure_stream(
stream: impl Stream<Item = Result<Self::T, ProcedureError>> + Send + 'static,
) -> ProcedureStream {
ProcedureStream::from_stream(stream)
}
}
impl<TErr, S, T> ResolverOutput<TErr> for crate::Stream<S>
where
TErr: Error,
S: Stream<Item = Result<T, TErr>> + Send + 'static,
T: ResolverOutput<TErr>,
{
type T = T::T;
fn data_type(types: &mut TypeCollection) -> DataType {
T::data_type(types) }
fn into_stream(self) -> impl Stream<Item = Result<Self::T, ProcedureError>> + Send + 'static {
self.0
.map_ok(|v| v.into_stream())
.map_err(|err| err.into_procedure_error())
.try_flatten()
}
fn into_procedure_stream(
stream: impl Stream<Item = Result<Self::T, ProcedureError>> + Send + 'static,
) -> ProcedureStream {
T::into_procedure_stream(stream)
}
}