rspc_legacy/
resolver_result.rs

1use std::{future::Future, marker::PhantomData};
2
3use serde::Serialize;
4use specta::Type;
5
6use crate::{
7    internal::{LayerResult, ValueOrStream},
8    Error, ExecError,
9};
10
11pub trait RequestLayer<TMarker> {
12    type Result: Type;
13
14    fn into_layer_result(self) -> Result<LayerResult, ExecError>;
15}
16
17pub struct SerializeMarker(PhantomData<()>);
18impl<T> RequestLayer<SerializeMarker> for T
19where
20    T: Serialize + Type,
21{
22    type Result = T;
23
24    fn into_layer_result(self) -> Result<LayerResult, ExecError> {
25        Ok(LayerResult::Ready(Ok(
26            serde_json::to_value(self).map_err(ExecError::SerializingResultErr)?
27        )))
28    }
29}
30
31pub struct ResultMarker(PhantomData<()>);
32impl<T> RequestLayer<ResultMarker> for Result<T, Error>
33where
34    T: Serialize + Type,
35{
36    type Result = T;
37
38    fn into_layer_result(self) -> Result<LayerResult, ExecError> {
39        Ok(LayerResult::Ready(Ok(serde_json::to_value(
40            self.map_err(ExecError::ErrResolverError)?,
41        )
42        .map_err(ExecError::SerializingResultErr)?)))
43    }
44}
45
46pub struct FutureMarker<TMarker>(PhantomData<TMarker>);
47impl<TFut, T, TMarker> RequestLayer<FutureMarker<TMarker>> for TFut
48where
49    TFut: Future<Output = T> + Send + 'static,
50    T: RequestLayer<TMarker> + Send,
51{
52    type Result = T::Result;
53
54    fn into_layer_result(self) -> Result<LayerResult, ExecError> {
55        Ok(LayerResult::Future(Box::pin(async move {
56            match self
57                .await
58                .into_layer_result()?
59                .into_value_or_stream()
60                .await?
61            {
62                ValueOrStream::Stream(_) => unreachable!(),
63                ValueOrStream::Value(v) => Ok(v),
64            }
65        })))
66    }
67}