change CallRemote to be based on remote context

This commit is contained in:
Aiden McClelland
2024-04-25 11:55:12 -06:00
parent c89e0abdb1
commit 3bc2c84c6f
4 changed files with 23 additions and 192 deletions

View File

@@ -84,7 +84,7 @@ impl<Context: crate::Context + Clone, Config: CommandFactory + FromArgMatches>
}
#[async_trait::async_trait]
pub trait CallRemote: crate::Context {
pub trait CallRemote<RemoteContext>: crate::Context {
async fn call_remote(&self, method: &str, params: Value) -> Result<Value, RpcError>;
}
@@ -207,8 +207,9 @@ where
type Err = RemoteHandler::Err;
}
#[async_trait::async_trait]
impl<Context: CallRemote, RemoteHandler> Handler for CallRemoteHandler<Context, RemoteHandler>
impl<Context, RemoteHandler> Handler for CallRemoteHandler<Context, RemoteHandler>
where
Context: CallRemote<RemoteHandler::Context>,
RemoteHandler: Handler,
RemoteHandler::Params: Serialize,
RemoteHandler::InheritedParams: Serialize,
@@ -237,9 +238,9 @@ where
}
}
}
impl<Context: CallRemote, RemoteHandler> PrintCliResult
for CallRemoteHandler<Context, RemoteHandler>
impl<Context, RemoteHandler> PrintCliResult for CallRemoteHandler<Context, RemoteHandler>
where
Context: CallRemote<RemoteHandler::Context>,
RemoteHandler: PrintCliResult<Context = Context>,
RemoteHandler::Params: Serialize,
RemoteHandler::InheritedParams: Serialize,

View File

@@ -40,7 +40,7 @@ pub trait HandlerExt: Handler + Sized {
) -> InheritanceHandler<Params, InheritedParams, Self, F>
where
F: Fn(Params, InheritedParams) -> Self::InheritedParams;
fn with_remote_cli<Context>(self) -> RemoteCli<Context, Self>;
fn with_call_remote<Context>(self) -> RemoteCaller<Context, Self>;
}
impl<T: Handler + Sized> HandlerExt for T {
@@ -90,8 +90,8 @@ impl<T: Handler + Sized> HandlerExt for T {
inherit: f,
}
}
fn with_remote_cli<Context>(self) -> RemoteCli<Context, Self> {
RemoteCli {
fn with_call_remote<Context>(self) -> RemoteCaller<Context, Self> {
RemoteCaller {
_phantom: PhantomData::new(),
handler: self,
}
@@ -452,11 +452,11 @@ where
}
}
pub struct RemoteCli<Context, H> {
pub struct RemoteCaller<Context, H> {
_phantom: PhantomData<Context>,
handler: H,
}
impl<Context, H: Clone> Clone for RemoteCli<Context, H> {
impl<Context, H: Clone> Clone for RemoteCaller<Context, H> {
fn clone(&self) -> Self {
Self {
_phantom: PhantomData::new(),
@@ -464,12 +464,12 @@ impl<Context, H: Clone> Clone for RemoteCli<Context, H> {
}
}
}
impl<Context, H: Debug> Debug for RemoteCli<Context, H> {
impl<Context, H: Debug> Debug for RemoteCaller<Context, H> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("RemoteCli").field(&self.handler).finish()
f.debug_tuple("RemoteCaller").field(&self.handler).finish()
}
}
impl<Context, H> HandlerTypes for RemoteCli<Context, H>
impl<Context, H> HandlerTypes for RemoteCaller<Context, H>
where
H: HandlerTypes,
{
@@ -479,9 +479,9 @@ where
type Err = H::Err;
}
#[async_trait::async_trait]
impl<Context, H> Handler for RemoteCli<Context, H>
impl<Context, H> Handler for RemoteCaller<Context, H>
where
Context: CallRemote,
Context: CallRemote<H::Context>,
H: Handler,
H::Params: Serialize,
H::InheritedParams: Serialize,
@@ -541,7 +541,7 @@ where
self.handler.method_from_dots(method, ctx_ty)
}
}
impl<Context, H> PrintCliResult for RemoteCli<Context, H>
impl<Context, H> PrintCliResult for RemoteCaller<Context, H>
where
Context: IntoContext,
H: PrintCliResult,

View File

@@ -1,169 +0,0 @@
use std::fmt::Display;
use std::str::FromStr;
use std::sync::Arc;
use futures::FutureExt;
use hyper::Request;
use rpc_toolkit::clap::Arg;
use rpc_toolkit::hyper::http::Error as HttpError;
use rpc_toolkit::hyper::Response;
use rpc_toolkit::serde::{Deserialize, Serialize};
use rpc_toolkit::url::Host;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{command, Context};
#[derive(Debug, Clone)]
pub struct AppState(Arc<ConfigSeed>);
impl From<AppState> for () {
fn from(_: AppState) -> Self {
()
}
}
#[derive(Debug)]
pub struct ConfigSeed {
host: Host,
port: u16,
}
impl Context for AppState {}
#[command(
about = "Does the thing",
subcommands("dothething2::<U>", self(dothething_impl(async)))
)]
async fn dothething<U>(
#[context] _ctx: AppState,
#[arg(short = 'a')] arg1: Option<String>,
#[arg(short = 'b', default)] val: String,
#[arg(short = 'c', help = "I am the flag `c`!", default)] arg3: bool,
#[arg(stdin)] structured: U,
) -> Result<(Option<String>, String, bool, U), RpcError>
where
U: Serialize + for<'a> Deserialize<'a> + FromStr + Clone + 'static,
U::Err: Display,
{
Ok((arg1, val, arg3, structured))
}
async fn dothething_impl<U: Serialize>(
ctx: AppState,
parent_data: (Option<String>, String, bool, U),
) -> Result<String, RpcError> {
Ok(format!(
"{:?}, {:?}, {}, {}, {}",
ctx,
parent_data.0,
parent_data.1,
parent_data.2,
serde_json::to_string_pretty(&parent_data.3)?
))
}
#[command(about = "Does the thing")]
fn dothething2<U>(
#[parent_data] parent_data: (Option<String>, String, bool, U),
#[arg(stdin)] structured2: U,
) -> Result<String, RpcError>
where
U: Serialize + for<'a> Deserialize<'a> + FromStr + Clone + 'static,
U::Err: Display,
{
Ok(format!(
"{:?}, {}, {}, {}, {}",
parent_data.0,
parent_data.1,
parent_data.2,
serde_json::to_string_pretty(&parent_data.3)?,
serde_json::to_string_pretty(&structured2)?,
))
}
// #[tokio::test]
// async fn test_rpc() {
// use tokio::io::AsyncWriteExt;
// let seed = Arc::new(ConfigSeed {
// host: Host::parse("localhost").unwrap(),
// port: 8000,
// });
// let server = rpc_server!({
// command: dothething::<String, _>,
// context: AppState(seed),
// middleware: [
// cors,
// ],
// });
// let handle = tokio::spawn(server);
// let mut cmd = tokio::process::Command::new("cargo")
// .arg("test")
// .arg("--package")
// .arg("rpc-toolkit")
// .arg("--test")
// .arg("test")
// .arg("--")
// .arg("cli_test")
// .arg("--exact")
// .arg("--nocapture")
// .arg("--")
// // .arg("-b")
// // .arg("test")
// .arg("dothething2")
// .stdin(std::process::Stdio::piped())
// .stdout(std::process::Stdio::piped())
// .spawn()
// .unwrap();
// cmd.stdin
// .take()
// .unwrap()
// .write_all(b"TEST\nHAHA")
// .await
// .unwrap();
// let out = cmd.wait_with_output().await.unwrap();
// assert!(out.status.success());
// assert!(dbg!(std::str::from_utf8(&out.stdout).unwrap())
// .contains("\nNone, test, false, \"TEST\", \"HAHA\"\n"));
// handle.abort();
// }
// #[test]
// fn cli_test() {
// let app = dothething::build_app();
// let mut skip = true;
// let args = std::iter::once(std::ffi::OsString::from("cli_test"))
// .chain(std::env::args_os().into_iter().skip_while(|a| {
// if a == "--" {
// skip = false;
// return true;
// }
// skip
// }))
// .collect::<Vec<_>>();
// if skip {
// return;
// }
// let matches = app.get_matches_from(args);
// let seed = Arc::new(ConfigSeed {
// host: Host::parse("localhost").unwrap(),
// port: 8000,
// });
// dothething::cli_handler::<String, _, _, _>(AppState(seed), (), None, &matches, "".into(), ())
// .unwrap();
// }
// #[test]
// #[ignore]
// fn cli_example() {
// run_cli! ({
// command: dothething::<String, _>,
// app: app => app
// .arg(Arg::with_name("host").long("host").short('h').takes_value(true))
// .arg(Arg::with_name("port").long("port").short('p').takes_value(true)),
// context: matches => AppState(Arc::new(ConfigSeed {
// host: Host::parse(matches.value_of("host").unwrap_or("localhost")).unwrap(),
// port: matches.value_of("port").unwrap_or("8000").parse().unwrap(),
// }))
// })
// }
// ////////////////////////////////////////////////

View File

@@ -1,4 +1,3 @@
use std::any::TypeId;
use std::ffi::OsString;
use std::fmt::Display;
use std::path::{Path, PathBuf};
@@ -62,7 +61,7 @@ impl Context for CliContext {
}
}
#[async_trait::async_trait]
impl CallRemote for CliContext {
impl CallRemote<ServerContext> for CliContext {
async fn call_remote(&self, method: &str, params: Value) -> Result<Value, RpcError> {
call_remote_socket(
tokio::net::UnixStream::connect(&self.0.host).await.unwrap(),
@@ -130,7 +129,7 @@ fn make_api() -> ParentHandler {
))
},
)
.with_remote_cli::<CliContext>(),
.with_call_remote::<CliContext>(),
)
.subcommand(
"hello",
@@ -174,7 +173,7 @@ fn make_api() -> ParentHandler {
.subcommand(
"error",
ParentHandler::<InheritParams>::new().root_handler(
from_fn(|c: CliContext, _: Empty, InheritParams { donde }| {
from_fn(|_: CliContext, _: Empty, InheritParams { .. }| {
Err::<String, _>(RpcError {
code: 1,
message: "This is an example message".into(),
@@ -199,14 +198,14 @@ fn test_cli() {
make_cli()
.run(
["test-cli", "hello", "me"]
.into_iter()
.iter()
.map(|s| OsString::from(s)),
)
.unwrap();
make_cli()
.run(
["test-cli", "fizz", "buzz"]
.into_iter()
.iter()
.map(|s| OsString::from(s)),
)
.unwrap();
@@ -230,7 +229,7 @@ async fn test_server() {
"echo",
"foo",
]
.into_iter()
.iter()
.map(|s| OsString::from(s)),
)
.unwrap();
@@ -242,7 +241,7 @@ async fn test_server() {
"echo",
"bar",
]
.into_iter()
.iter()
.map(|s| OsString::from(s)),
)
.unwrap();