rpc_toolkit/handler/
mod.rs

1use std::any::TypeId;
2use std::collections::VecDeque;
3use std::fmt::Debug;
4use std::marker::PhantomData;
5use std::ops::Deref;
6use std::sync::Arc;
7
8use clap::{ArgMatches, Command, Parser};
9use futures::Future;
10use imbl_value::imbl::OrdMap;
11use imbl_value::Value;
12use serde::de::DeserializeOwned;
13use serde::{Deserialize, Serialize};
14use yajrc::RpcError;
15
16use crate::util::{internal_error, invalid_params, Flat};
17
18pub mod adapters;
19pub mod from_fn;
20pub mod parent;
21
22pub use adapters::*;
23pub use from_fn::*;
24pub use parent::*;
25
26pub(crate) struct HandleAnyArgs<Context, Inherited> {
27    pub(crate) context: Context,
28    pub(crate) parent_method: VecDeque<&'static str>,
29    pub(crate) method: VecDeque<&'static str>,
30    pub(crate) params: Value,
31    pub(crate) inherited: Inherited,
32}
33impl<Context: crate::Context, Inherited: Send + Sync> HandleAnyArgs<Context, Inherited> {
34    fn downcast<H>(self) -> Result<HandlerArgsFor<Context, H>, imbl_value::Error>
35    where
36        H: HandlerTypes,
37        H::InheritedParams: OrEmpty<Inherited>,
38        H::Params: DeserializeOwned,
39    {
40        let Self {
41            context,
42            parent_method,
43            method,
44            params,
45            inherited,
46        } = self;
47        Ok(HandlerArgs {
48            context,
49            parent_method,
50            method,
51            params: imbl_value::from_value(params.clone())?,
52            inherited_params: OrEmpty::from_t(inherited),
53            raw_params: params,
54        })
55    }
56}
57
58#[async_trait::async_trait]
59pub(crate) trait HandleAny<Context>: Send + Sync {
60    type Inherited: Send;
61    fn handle_sync(
62        &self,
63        handle_args: HandleAnyArgs<Context, Self::Inherited>,
64    ) -> Result<Value, RpcError>;
65    async fn handle_async(
66        &self,
67        handle_args: HandleAnyArgs<Context, Self::Inherited>,
68    ) -> Result<Value, RpcError>;
69    fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value>;
70    fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>>;
71    fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>>;
72}
73#[async_trait::async_trait]
74impl<Context: crate::Context, T: HandleAny<Context>> HandleAny<Context> for Arc<T> {
75    type Inherited = T::Inherited;
76    fn handle_sync(
77        &self,
78        handle_args: HandleAnyArgs<Context, Self::Inherited>,
79    ) -> Result<Value, RpcError> {
80        self.deref().handle_sync(handle_args)
81    }
82    async fn handle_async(
83        &self,
84        handle_args: HandleAnyArgs<Context, Self::Inherited>,
85    ) -> Result<Value, RpcError> {
86        self.deref().handle_async(handle_args).await
87    }
88    fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
89        self.deref().metadata(method)
90    }
91    fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
92        self.deref().method_from_dots(method)
93    }
94    fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>> {
95        self.deref().cli()
96    }
97}
98
99pub(crate) trait CliBindingsAny<Context> {
100    type Inherited;
101    fn cli_command(&self) -> Command;
102    fn cli_parse(
103        &self,
104        matches: &ArgMatches,
105    ) -> Result<(VecDeque<&'static str>, Value), clap::Error>;
106    fn cli_display(
107        &self,
108        handle_args: HandleAnyArgs<Context, Self::Inherited>,
109        result: Value,
110    ) -> Result<(), RpcError>;
111}
112
113pub trait CliBindings<Context: crate::Context>: HandlerTypes {
114    const NO_CLI: bool = false;
115    fn cli_command(&self) -> Command;
116    fn cli_parse(
117        &self,
118        matches: &ArgMatches,
119    ) -> Result<(VecDeque<&'static str>, Value), clap::Error>;
120    fn cli_display(
121        &self,
122        handle_args: HandlerArgsFor<Context, Self>,
123        result: Self::Ok,
124    ) -> Result<(), Self::Err>;
125}
126
127pub trait PrintCliResult<Context: crate::Context>: HandlerTypes {
128    fn print(
129        &self,
130        handle_args: HandlerArgsFor<Context, Self>,
131        result: Self::Ok,
132    ) -> Result<(), Self::Err>;
133}
134
135#[allow(private_interfaces)]
136pub struct DynHandler<Context, Inherited>(Arc<dyn HandleAny<Context, Inherited = Inherited>>);
137impl<Context: crate::Context, Inherited> DynHandler<Context, Inherited> {
138    pub fn new<C, H>(handler: H) -> Option<Self>
139    where
140        C: crate::Context,
141        WithContext<C, H>: Handler<Inherited>,
142    {
143        WithContext::<C, _>::new(handler).handler_for::<Context>()
144    }
145}
146impl<Context, Inherited> Clone for DynHandler<Context, Inherited> {
147    fn clone(&self) -> Self {
148        Self(self.0.clone())
149    }
150}
151impl<Context, Inherited> Debug for DynHandler<Context, Inherited> {
152    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
153        f.debug_struct("DynHandler").finish()
154    }
155}
156#[async_trait::async_trait]
157impl<Context: crate::Context, Inherited: Send> HandleAny<Context>
158    for DynHandler<Context, Inherited>
159{
160    type Inherited = Inherited;
161    fn handle_sync(
162        &self,
163        handle_args: HandleAnyArgs<Context, Self::Inherited>,
164    ) -> Result<Value, RpcError> {
165        self.0.handle_sync(handle_args)
166    }
167    async fn handle_async(
168        &self,
169        handle_args: HandleAnyArgs<Context, Self::Inherited>,
170    ) -> Result<Value, RpcError> {
171        self.0.handle_async(handle_args).await
172    }
173    fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
174        self.0.metadata(method)
175    }
176    fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
177        self.0.method_from_dots(method)
178    }
179    fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>> {
180        self.0.cli()
181    }
182}
183
184#[allow(type_alias_bounds)]
185pub type HandlerArgsFor<Context: crate::Context, H: HandlerTypes + ?Sized> =
186    HandlerArgs<Context, H::Params, H::InheritedParams>;
187
188#[derive(Debug, Clone)]
189pub struct HandlerArgs<
190    Context: crate::Context,
191    Params: Send + Sync = Empty,
192    InheritedParams: Send + Sync = Empty,
193> {
194    pub context: Context,
195    pub parent_method: VecDeque<&'static str>,
196    pub method: VecDeque<&'static str>,
197    pub params: Params,
198    pub inherited_params: InheritedParams,
199    pub raw_params: Value,
200}
201
202pub trait HandlerTypes {
203    type Params: Send + Sync;
204    type InheritedParams: Send + Sync;
205    type Ok: Send + Sync;
206    type Err: Send + Sync;
207}
208
209pub trait HandlerFor<Context: crate::Context>:
210    HandlerTypes + Clone + Send + Sync + 'static
211{
212    fn handle_sync(
213        &self,
214        handle_args: HandlerArgsFor<Context, Self>,
215    ) -> Result<Self::Ok, Self::Err> {
216        if let Some(rt) = handle_args.context.runtime() {
217            rt.block_on(self.handle_async(handle_args))
218        } else {
219            tokio::runtime::Handle::current().block_on(self.handle_async(handle_args))
220        }
221    }
222    fn handle_async(
223        &self,
224        handle_args: HandlerArgsFor<Context, Self>,
225    ) -> impl Future<Output = Result<Self::Ok, Self::Err>> + Send;
226    fn handle_async_with_sync<'a>(
227        &'a self,
228        handle_args: HandlerArgsFor<Context, Self>,
229    ) -> impl Future<Output = Result<Self::Ok, Self::Err>> + Send + 'a {
230        async move { self.handle_sync(handle_args) }
231    }
232    fn handle_async_with_sync_blocking<'a>(
233        &'a self,
234        handle_args: HandlerArgsFor<Context, Self>,
235    ) -> impl Future<Output = Result<Self::Ok, Self::Err>> + Send + 'a {
236        async move {
237            let s = self.clone();
238            if let Some(rt) = handle_args.context.runtime() {
239                rt.spawn_blocking(move || s.handle_sync(handle_args)).await
240            } else {
241                tokio::runtime::Handle::current()
242                    .spawn_blocking(move || s.handle_sync(handle_args))
243                    .await
244            }
245            .unwrap()
246        }
247    }
248    #[allow(unused_variables)]
249    fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
250        OrdMap::new()
251    }
252    #[allow(unused_variables)]
253    fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
254        if method.is_empty() {
255            Some(VecDeque::new())
256        } else {
257            None
258        }
259    }
260}
261
262pub trait Handler<Inherited> {
263    type H: HandlerTypes;
264    fn handler_for<C: crate::Context>(self) -> Option<DynHandler<C, Inherited>>;
265}
266
267pub struct WithContext<Context, H> {
268    _phantom: PhantomData<Context>,
269    handler: H,
270}
271impl<Context, H> WithContext<Context, H> {
272    pub fn new(handler: H) -> Self {
273        Self {
274            _phantom: PhantomData,
275            handler,
276        }
277    }
278}
279
280impl<Context, Inherited, H> Handler<Inherited> for WithContext<Context, H>
281where
282    Context: crate::Context,
283    H: HandlerFor<Context> + CliBindings<Context>,
284    H::Ok: Serialize + DeserializeOwned,
285    H::Params: DeserializeOwned,
286    H::InheritedParams: OrEmpty<Inherited>,
287    RpcError: From<H::Err>,
288    Inherited: Send + Sync + 'static,
289{
290    type H = H;
291    fn handler_for<C: crate::Context>(self) -> Option<DynHandler<C, Inherited>> {
292        if TypeId::of::<Context>() == TypeId::of::<C>() {
293            Some(unsafe {
294                std::mem::transmute::<DynHandler<Context, Inherited>, DynHandler<C, Inherited>>(
295                    DynHandler(Arc::new(AnyHandler::new(self.handler))),
296                )
297            })
298        } else {
299            None
300        }
301    }
302}
303
304pub(crate) struct AnyHandler<Context, Inherited, H> {
305    _phantom: PhantomData<(Context, Inherited)>,
306    handler: H,
307}
308impl<Context, Inherited, H> AnyHandler<Context, Inherited, H> {
309    pub(crate) fn new(handler: H) -> Self {
310        Self {
311            _phantom: PhantomData,
312            handler,
313        }
314    }
315}
316impl<Context, Inherited, H: std::fmt::Debug> std::fmt::Debug for AnyHandler<Context, Inherited, H> {
317    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
318        f.debug_struct("AnyHandler")
319            .field("handler", &self.handler)
320            .finish()
321    }
322}
323
324#[async_trait::async_trait]
325impl<Context, Inherited, H> HandleAny<Context> for AnyHandler<Context, Inherited, H>
326where
327    Context: crate::Context,
328    H: HandlerFor<Context> + CliBindings<Context>,
329    H::Params: DeserializeOwned,
330    H::Ok: Serialize + DeserializeOwned,
331    H::InheritedParams: OrEmpty<Inherited>,
332    RpcError: From<H::Err>,
333    Inherited: Send + Sync,
334{
335    type Inherited = Inherited;
336    fn handle_sync(
337        &self,
338        handle_args: HandleAnyArgs<Context, Self::Inherited>,
339    ) -> Result<Value, RpcError> {
340        imbl_value::to_value(
341            &self
342                .handler
343                .handle_sync(handle_args.downcast::<H>().map_err(invalid_params)?)?,
344        )
345        .map_err(internal_error)
346    }
347    async fn handle_async(
348        &self,
349        handle_args: HandleAnyArgs<Context, Self::Inherited>,
350    ) -> Result<Value, RpcError> {
351        imbl_value::to_value(
352            &self
353                .handler
354                .handle_async(handle_args.downcast::<H>().map_err(invalid_params)?)
355                .await?,
356        )
357        .map_err(internal_error)
358    }
359    fn metadata(&self, method: VecDeque<&'static str>) -> OrdMap<&'static str, Value> {
360        self.handler.metadata(method)
361    }
362    fn method_from_dots(&self, method: &str) -> Option<VecDeque<&'static str>> {
363        self.handler.method_from_dots(method)
364    }
365    fn cli(&self) -> Option<&dyn CliBindingsAny<Context, Inherited = Self::Inherited>> {
366        if H::NO_CLI {
367            None
368        } else {
369            Some(self)
370        }
371    }
372}
373
374impl<Context, Inherited, H> CliBindingsAny<Context> for AnyHandler<Context, Inherited, H>
375where
376    Context: crate::Context,
377    H: CliBindings<Context>,
378    H::Params: DeserializeOwned,
379    H::Ok: Serialize + DeserializeOwned,
380    RpcError: From<H::Err>,
381    H::InheritedParams: OrEmpty<Inherited>,
382    Inherited: Send + Sync,
383{
384    type Inherited = Inherited;
385    fn cli_command(&self) -> Command {
386        self.handler.cli_command()
387    }
388    fn cli_parse(
389        &self,
390        matches: &ArgMatches,
391    ) -> Result<(VecDeque<&'static str>, Value), clap::Error> {
392        self.handler.cli_parse(matches)
393    }
394    fn cli_display(
395        &self,
396        handle_args: HandleAnyArgs<Context, Self::Inherited>,
397        result: Value,
398    ) -> Result<(), RpcError> {
399        self.handler
400            .cli_display(
401                handle_args.downcast::<H>().map_err(invalid_params)?,
402                imbl_value::from_value(result).map_err(internal_error)?,
403            )
404            .map_err(RpcError::from)
405    }
406}
407
408#[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)]
409pub struct Empty {}
410
411pub(crate) trait OrEmpty<T> {
412    fn from_t(t: T) -> Self;
413}
414impl<T> OrEmpty<T> for T {
415    fn from_t(t: T) -> Self {
416        t
417    }
418}
419impl<A, B> OrEmpty<Flat<A, B>> for Empty {
420    fn from_t(_: Flat<A, B>) -> Self {
421        Empty {}
422    }
423}
424
425#[derive(Debug, Clone, Copy, Deserialize, Serialize, Parser)]
426pub enum Never {}