add "Extra" to call_remote

This commit is contained in:
Aiden McClelland
2024-05-03 13:06:30 -06:00
parent 94da122d6c
commit 320d832359
4 changed files with 91 additions and 26 deletions

View File

@@ -15,7 +15,7 @@ use yajrc::{Id, RpcError};
use crate::util::{internal_error, parse_error, PhantomData}; use crate::util::{internal_error, parse_error, PhantomData};
use crate::{ use crate::{
AnyHandler, CliBindingsAny, DynHandler, HandleAny, HandleAnyArgs, Handler, HandlerArgs, AnyHandler, CliBindingsAny, DynHandler, Empty, HandleAny, HandleAnyArgs, Handler, HandlerArgs,
HandlerArgsFor, HandlerTypes, IntoContext, Name, ParentHandler, PrintCliResult, HandlerArgsFor, HandlerTypes, IntoContext, Name, ParentHandler, PrintCliResult,
}; };
@@ -84,11 +84,12 @@ impl<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches>
} }
} }
pub trait CallRemote<RemoteContext>: crate::Context { pub trait CallRemote<RemoteContext, Extra = Empty>: crate::Context {
fn call_remote( fn call_remote(
&self, &self,
method: &str, method: &str,
params: Value, params: Value,
extra: Extra,
) -> impl Future<Output = Result<Value, RpcError>> + Send; ) -> impl Future<Output = Result<Value, RpcError>> + Send;
} }
@@ -171,7 +172,7 @@ pub async fn call_remote_socket(
.result .result
} }
pub struct CallRemoteHandler<Context, RemoteHandler> { struct CallRemoteHandler<Context, RemoteHandler> {
_phantom: PhantomData<Context>, _phantom: PhantomData<Context>,
handler: RemoteHandler, handler: RemoteHandler,
} }
@@ -232,7 +233,11 @@ where
.collect::<Vec<_>>(); .collect::<Vec<_>>();
match handle_args match handle_args
.context .context
.call_remote(&full_method.join("."), handle_args.raw_params.clone()) .call_remote(
&full_method.join("."),
handle_args.raw_params.clone(),
Empty {},
)
.await .await
{ {
Ok(a) => imbl_value::from_value(a) Ok(a) => imbl_value::from_value(a)

View File

@@ -10,11 +10,11 @@ use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
use yajrc::RpcError; use yajrc::RpcError;
use crate::util::{internal_error, Flat, PhantomData}; use crate::util::{internal_error, invalid_params, without, Flat, PhantomData};
use crate::{ use crate::{
iter_from_ctx_and_handler, AnyContext, AnyHandler, CallRemote, CliBindings, DynHandler, iter_from_ctx_and_handler, AnyContext, AnyHandler, CallRemote, CliBindings, DynHandler,
EitherContext, Handler, HandlerArgs, HandlerArgsFor, HandlerTypes, IntoContext, IntoHandlers, EitherContext, Empty, Handler, HandlerArgs, HandlerArgsFor, HandlerTypes, IntoContext,
OrEmpty, PrintCliResult, IntoHandlers, OrEmpty, PrintCliResult,
}; };
pub trait HandlerExt: Handler + Sized { pub trait HandlerExt: Handler + Sized {
@@ -40,7 +40,7 @@ pub trait HandlerExt: Handler + Sized {
) -> InheritanceHandler<Params, InheritedParams, Self, F> ) -> InheritanceHandler<Params, InheritedParams, Self, F>
where where
F: Fn(Params, InheritedParams) -> Self::InheritedParams; F: Fn(Params, InheritedParams) -> Self::InheritedParams;
fn with_call_remote<Context>(self) -> RemoteCaller<Context, Self>; fn with_call_remote<Context, Extra>(self) -> RemoteCaller<Context, Self, Extra>;
} }
impl<T: Handler + Sized> HandlerExt for T { impl<T: Handler + Sized> HandlerExt for T {
@@ -90,7 +90,7 @@ impl<T: Handler + Sized> HandlerExt for T {
inherit: f, inherit: f,
} }
} }
fn with_call_remote<Context>(self) -> RemoteCaller<Context, Self> { fn with_call_remote<Context, Extra>(self) -> RemoteCaller<Context, Self, Extra> {
RemoteCaller { RemoteCaller {
_phantom: PhantomData::new(), _phantom: PhantomData::new(),
handler: self, handler: self,
@@ -452,11 +452,11 @@ where
} }
} }
pub struct RemoteCaller<Context, H> { pub struct RemoteCaller<Context, H, Extra = Empty> {
_phantom: PhantomData<Context>, _phantom: PhantomData<(Context, Extra)>,
handler: H, handler: H,
} }
impl<Context, H: Clone> Clone for RemoteCaller<Context, H> { impl<Context, H: Clone, Extra> Clone for RemoteCaller<Context, H, Extra> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
_phantom: PhantomData::new(), _phantom: PhantomData::new(),
@@ -464,29 +464,31 @@ impl<Context, H: Clone> Clone for RemoteCaller<Context, H> {
} }
} }
} }
impl<Context, H: Debug> Debug for RemoteCaller<Context, H> { impl<Context, H: Debug, Extra> Debug for RemoteCaller<Context, H, Extra> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("RemoteCaller").field(&self.handler).finish() f.debug_tuple("RemoteCaller").field(&self.handler).finish()
} }
} }
impl<Context, H> HandlerTypes for RemoteCaller<Context, H> impl<Context, H, Extra> HandlerTypes for RemoteCaller<Context, H, Extra>
where where
H: HandlerTypes, H: HandlerTypes,
Extra: Send + Sync + 'static,
{ {
type Params = H::Params; type Params = Flat<H::Params, Extra>;
type InheritedParams = H::InheritedParams; type InheritedParams = H::InheritedParams;
type Ok = H::Ok; type Ok = H::Ok;
type Err = H::Err; type Err = H::Err;
} }
impl<Context, H> Handler for RemoteCaller<Context, H> impl<Context, H, Extra> Handler for RemoteCaller<Context, H, Extra>
where where
Context: CallRemote<H::Context>, Context: CallRemote<H::Context, Extra>,
H: Handler, H: Handler,
H::Params: Serialize, H::Params: Serialize,
H::InheritedParams: Serialize, H::InheritedParams: Serialize,
H::Ok: DeserializeOwned, H::Ok: DeserializeOwned,
H::Err: From<RpcError>, H::Err: From<RpcError>,
Extra: Serialize + Send + Sync + 'static,
{ {
type Context = EitherContext<Context, H::Context>; type Context = EitherContext<Context, H::Context>;
async fn handle_async( async fn handle_async(
@@ -495,7 +497,7 @@ where
context, context,
parent_method, parent_method,
method, method,
params, params: Flat(params, extra),
inherited_params, inherited_params,
raw_params, raw_params,
}: HandlerArgsFor<Self::Context, Self>, }: HandlerArgsFor<Self::Context, Self>,
@@ -504,7 +506,11 @@ where
EitherContext::C1(context) => { EitherContext::C1(context) => {
let full_method = parent_method.into_iter().chain(method).collect::<Vec<_>>(); let full_method = parent_method.into_iter().chain(method).collect::<Vec<_>>();
match context match context
.call_remote(&full_method.join("."), raw_params.clone()) .call_remote(
&full_method.join("."),
without(raw_params, &extra).map_err(invalid_params)?,
extra,
)
.await .await
{ {
Ok(a) => imbl_value::from_value(a) Ok(a) => imbl_value::from_value(a)
@@ -553,7 +559,7 @@ where
context, context,
parent_method, parent_method,
method, method,
params, params: Flat(params, _),
inherited_params, inherited_params,
raw_params, raw_params,
}: HandlerArgsFor<Self::Context, Self>, }: HandlerArgsFor<Self::Context, Self>,

View File

@@ -10,10 +10,21 @@ use serde::{Deserialize, Serialize};
use yajrc::RpcError; use yajrc::RpcError;
pub fn extract<T: DeserializeOwned>(value: &Value) -> Result<T, RpcError> { pub fn extract<T: DeserializeOwned>(value: &Value) -> Result<T, RpcError> {
imbl_value::from_value(value.clone()).map_err(|e| RpcError { imbl_value::from_value(value.clone()).map_err(invalid_params)
data: Some(e.to_string().into()), }
..yajrc::INVALID_PARAMS_ERROR
}) pub fn without<T: Serialize>(value: Value, remove: &T) -> Result<Value, imbl_value::Error> {
let to_remove = imbl_value::to_value(remove)?;
let (Value::Object(mut value), Value::Object(to_remove)) = (value, to_remove) else {
return Err(imbl_value::Error {
kind: imbl_value::ErrorKind::Serialization,
source: serde_json::Error::custom("params must be object"),
});
};
for k in to_remove.keys() {
value.remove(k);
}
Ok(Value::Object(value))
} }
pub fn combine(v1: Value, v2: Value) -> Result<Value, imbl_value::Error> { pub fn combine(v1: Value, v2: Value) -> Result<Value, imbl_value::Error> {
@@ -103,6 +114,49 @@ where
.serialize(serializer) .serialize(serializer)
} }
} }
impl<A, B> clap::CommandFactory for Flat<A, B>
where
A: clap::CommandFactory,
B: clap::Args,
{
fn command() -> clap::Command {
B::augment_args(A::command())
}
fn command_for_update() -> clap::Command {
B::augment_args_for_update(A::command_for_update())
}
}
impl<A, B> clap::FromArgMatches for Flat<A, B>
where
A: clap::FromArgMatches,
B: clap::FromArgMatches,
{
fn from_arg_matches(matches: &clap::ArgMatches) -> Result<Self, clap::Error> {
Ok(Self(
A::from_arg_matches(matches)?,
B::from_arg_matches(matches)?,
))
}
fn from_arg_matches_mut(matches: &mut clap::ArgMatches) -> Result<Self, clap::Error> {
Ok(Self(
A::from_arg_matches_mut(matches)?,
B::from_arg_matches_mut(matches)?,
))
}
fn update_from_arg_matches(&mut self, matches: &clap::ArgMatches) -> Result<(), clap::Error> {
self.0.update_from_arg_matches(matches)?;
self.1.update_from_arg_matches(matches)?;
Ok(())
}
fn update_from_arg_matches_mut(
&mut self,
matches: &mut clap::ArgMatches,
) -> Result<(), clap::Error> {
self.0.update_from_arg_matches_mut(matches)?;
self.1.update_from_arg_matches_mut(matches)?;
Ok(())
}
}
pub fn poll_select_all<'a, T>( pub fn poll_select_all<'a, T>(
futs: &mut Vec<BoxFuture<'a, T>>, futs: &mut Vec<BoxFuture<'a, T>>,

View File

@@ -62,7 +62,7 @@ impl Context for CliContext {
} }
impl CallRemote<ServerContext> for CliContext { impl CallRemote<ServerContext> for CliContext {
async fn call_remote(&self, method: &str, params: Value) -> Result<Value, RpcError> { async fn call_remote(&self, method: &str, params: Value, _: Empty) -> Result<Value, RpcError> {
call_remote_socket( call_remote_socket(
tokio::net::UnixStream::connect(&self.0.host).await.unwrap(), tokio::net::UnixStream::connect(&self.0.host).await.unwrap(),
method, method,
@@ -129,7 +129,7 @@ fn make_api() -> ParentHandler {
)) ))
}, },
) )
.with_call_remote::<CliContext>(), .with_call_remote::<CliContext, Empty>(),
) )
.subcommand( .subcommand(
"hello", "hello",