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
21pub struct DoubleArgMarker<TArg, TResultMarker>(
70 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 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}