rspc_legacy/
resolver.rs

1use std::marker::PhantomData;
2
3use futures::{Stream, StreamExt};
4use serde::{de::DeserializeOwned, Serialize};
5use serde_json::Value;
6use specta::{Type, TypeCollection};
7
8use crate::{
9    internal::{LayerResult, ProcedureDataType},
10    ExecError, RequestLayer,
11};
12
13pub trait Resolver<TCtx, TMarker> {
14    type Result;
15
16    fn exec(&self, ctx: TCtx, input: Value) -> Result<LayerResult, ExecError>;
17
18    fn typedef(defs: &mut TypeCollection) -> ProcedureDataType;
19}
20
21// pub struct NoArgMarker<TResultMarker>(/* private */ PhantomData<TResultMarker>);
22// impl<TFunc, TCtx, TResult, TResultMarker> Resolver<TCtx, NoArgMarker<TResultMarker>> for TFunc
23// where
24//     TFunc: Fn() -> TResult,
25//     TResult: IntoLayerResult<TResultMarker> + Type,
26// {
27//     fn exec(&self, _ctx: TCtx, _arg: Value) -> Result<LayerResult, ExecError> {
28//         self().into_layer_result()
29//     }
30//
31//     fn typedef(defs: &mut TypeDefs) -> ProcedureDataType {
32//         ProcedureDataType {
33//             arg_ty: <() as Type>::def(DefOpts {
34//                 parent_inline: true,
35//                 type_map: defs,
36//             }),
37//             result_ty: <TResult as Type>::def(DefOpts {
38//                 parent_inline: true,
39//                 type_map: defs,
40//             }),
41//         }
42//     }
43// }
44//
45// pub struct SingleArgMarker<TResultMarker>(/* private */ PhantomData<TResultMarker>);
46// impl<TFunc, TCtx, TResult, TResultMarker> Resolver<TCtx, SingleArgMarker<TResultMarker>> for TFunc
47// where
48//     TFunc: Fn(TCtx) -> TResult,
49//     TResult: IntoLayerResult<TResultMarker>,
50// {
51//     fn exec(&self, ctx: TCtx, _arg: Value) -> Result<LayerResult, ExecError> {
52//         self(ctx).into_layer_result()
53//     }
54//
55//     fn typedef(defs: &mut TypeDefs) -> ProcedureDataType {
56//         ProcedureDataType {
57//             arg_ty: <() as Type>::def(DefOpts {
58//                 parent_inline: true,
59//                 type_map: defs,
60//             }),
61//             result_ty: <TResult::Result as Type>::def(DefOpts {
62//                 parent_inline: true,
63//                 type_map: defs,
64//             }),
65//         }
66//     }
67// }
68
69pub struct DoubleArgMarker<TArg, TResultMarker>(
70    /* private */ PhantomData<(TArg, TResultMarker)>,
71);
72impl<TFunc, TCtx, TArg, TResult, TResultMarker> Resolver<TCtx, DoubleArgMarker<TArg, TResultMarker>>
73    for TFunc
74where
75    TArg: DeserializeOwned + Type,
76    TFunc: Fn(TCtx, TArg) -> TResult,
77    TResult: RequestLayer<TResultMarker>,
78{
79    type Result = TResult;
80
81    fn exec(&self, ctx: TCtx, input: Value) -> Result<LayerResult, ExecError> {
82        let input = serde_json::from_value(input).map_err(ExecError::DeserializingArgErr)?;
83        self(ctx, input).into_layer_result()
84    }
85
86    fn typedef(defs: &mut TypeCollection) -> ProcedureDataType {
87        typedef::<TArg, TResult::Result>(defs)
88    }
89}
90
91pub trait StreamResolver<TCtx, TMarker> {
92    fn exec(&self, ctx: TCtx, input: Value) -> Result<LayerResult, ExecError>;
93
94    fn typedef(defs: &mut TypeCollection) -> ProcedureDataType;
95}
96
97pub struct DoubleArgStreamMarker<TArg, TResult, TStream>(
98    /* private */ PhantomData<(TArg, TResult, TStream)>,
99);
100impl<TFunc, TCtx, TArg, TResult, TStream>
101    StreamResolver<TCtx, DoubleArgStreamMarker<TArg, TResult, TStream>> for TFunc
102where
103    TArg: DeserializeOwned + Type,
104    TFunc: Fn(TCtx, TArg) -> TStream,
105    TStream: Stream<Item = TResult> + Send + Sync + 'static,
106    TResult: Serialize + Type,
107{
108    fn exec(&self, ctx: TCtx, input: Value) -> Result<LayerResult, ExecError> {
109        let input = serde_json::from_value(input).map_err(ExecError::DeserializingArgErr)?;
110        Ok(LayerResult::Stream(Box::pin(self(ctx, input).map(|v| {
111            serde_json::to_value(&v).map_err(ExecError::SerializingResultErr)
112        }))))
113    }
114
115    fn typedef(defs: &mut TypeCollection) -> ProcedureDataType {
116        typedef::<TArg, TResult>(defs)
117    }
118}
119
120pub fn typedef<TArg: Type, TResult: Type>(defs: &mut TypeCollection) -> ProcedureDataType {
121    let arg_ty = TArg::reference(defs, &[]).inner;
122    let result_ty = TResult::reference(defs, &[]).inner;
123
124    ProcedureDataType { arg_ty, result_ty }
125}