rspc_legacy/
resolver_result.rs1use 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}