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 {}