mirror of
https://github.com/Start9Labs/rpc-toolkit.git
synced 2026-03-26 02:11:56 +00:00
ditch SeedableContext
This commit is contained in:
@@ -14,20 +14,20 @@ pub fn build(args: RpcServerArgs) -> TokenStream {
|
|||||||
ident: Ident::new("rpc_handler", command.span()),
|
ident: Ident::new("rpc_handler", command.span()),
|
||||||
arguments,
|
arguments,
|
||||||
});
|
});
|
||||||
let seed = args.seed;
|
let ctx = args.ctx;
|
||||||
let status_fn = args
|
let status_fn = args
|
||||||
.status_fn
|
.status_fn
|
||||||
.unwrap_or_else(|| syn::parse2(quote! { |_| rpc_toolkit::hyper::StatusCode::OK }).unwrap());
|
.unwrap_or_else(|| syn::parse2(quote! { |_| rpc_toolkit::hyper::StatusCode::OK }).unwrap());
|
||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
let seed = #seed;
|
let ctx = #ctx;
|
||||||
let status_fn = #status_fn;
|
let status_fn = #status_fn;
|
||||||
let (builder, ctx_phantom) = rpc_toolkit::rpc_server_helpers::make_builder(seed.clone());
|
let (builder, ctx_phantom) = rpc_toolkit::rpc_server_helpers::make_builder(&ctx);
|
||||||
let make_svc = rpc_toolkit::hyper::service::make_service_fn(move |_| {
|
let make_svc = rpc_toolkit::hyper::service::make_service_fn(move |_| {
|
||||||
let seed = seed.clone();
|
let ctx = ctx.clone();
|
||||||
async move {
|
async move {
|
||||||
Ok::<_, hyper::Error>(rpc_toolkit::hyper::service::service_fn(move |mut req| {
|
Ok::<_, rpc_toolkit::hyper::Error>(rpc_toolkit::hyper::service::service_fn(move |mut req| {
|
||||||
let seed = seed.clone();
|
let ctx = ctx.clone();
|
||||||
async move {
|
async move {
|
||||||
let rpc_req = rpc_toolkit::rpc_server_helpers::make_request(&mut req).await;
|
let rpc_req = rpc_toolkit::rpc_server_helpers::make_request(&mut req).await;
|
||||||
rpc_toolkit::rpc_server_helpers::to_response(
|
rpc_toolkit::rpc_server_helpers::to_response(
|
||||||
@@ -36,7 +36,7 @@ pub fn build(args: RpcServerArgs) -> TokenStream {
|
|||||||
Ok(rpc_req) => Ok((
|
Ok(rpc_req) => Ok((
|
||||||
rpc_req.id,
|
rpc_req.id,
|
||||||
#command(
|
#command(
|
||||||
rpc_toolkit::rpc_server_helpers::bind_type(ctx_phantom, rpc_toolkit::SeedableContext::new(seed)),
|
rpc_toolkit::rpc_server_helpers::bind_type(ctx_phantom, ctx),
|
||||||
rpc_toolkit::yajrc::RpcMethod::as_str(&rpc_req.method),
|
rpc_toolkit::yajrc::RpcMethod::as_str(&rpc_req.method),
|
||||||
rpc_req.params,
|
rpc_req.params,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use syn::*;
|
|||||||
|
|
||||||
pub struct RpcServerArgs {
|
pub struct RpcServerArgs {
|
||||||
command: Path,
|
command: Path,
|
||||||
seed: Expr,
|
ctx: Expr,
|
||||||
status_fn: Option<Expr>,
|
status_fn: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ impl Parse for RpcServerArgs {
|
|||||||
fn parse(input: ParseStream) -> Result<Self> {
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
let command = input.parse()?;
|
let command = input.parse()?;
|
||||||
let _: token::Comma = input.parse()?;
|
let _: token::Comma = input.parse()?;
|
||||||
let seed = input.parse()?;
|
let ctx = input.parse()?;
|
||||||
if !input.is_empty() {
|
if !input.is_empty() {
|
||||||
let _: token::Comma = input.parse()?;
|
let _: token::Comma = input.parse()?;
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ impl Parse for RpcServerArgs {
|
|||||||
};
|
};
|
||||||
Ok(RpcServerArgs {
|
Ok(RpcServerArgs {
|
||||||
command,
|
command,
|
||||||
seed,
|
ctx,
|
||||||
status_fn,
|
status_fn,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,17 +30,17 @@ pub fn build(args: RunCliArgs) -> TokenStream {
|
|||||||
} else {
|
} else {
|
||||||
quote! { #command::build_app() }
|
quote! { #command::build_app() }
|
||||||
};
|
};
|
||||||
let make_ctx = if let Some(make_seed) = args.make_seed {
|
let make_ctx = if let Some(make_ctx) = args.make_ctx {
|
||||||
let ident = make_seed.matches_ident;
|
let ident = make_ctx.matches_ident;
|
||||||
let body = make_seed.body;
|
let body = make_ctx.body;
|
||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
let #ident = &rpc_toolkit_matches;
|
let #ident = &rpc_toolkit_matches;
|
||||||
rpc_toolkit::SeedableContext::new(#body)
|
#body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! { rpc_toolkit::SeedableContext::new(&rpc_toolkit_matches) }
|
quote! { &rpc_toolkit_matches }
|
||||||
};
|
};
|
||||||
let exit_fn = args
|
let exit_fn = args
|
||||||
.exit_fn
|
.exit_fn
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use syn::*;
|
use syn::*;
|
||||||
|
|
||||||
pub struct MakeSeed {
|
pub struct MakeCtx {
|
||||||
matches_ident: Ident,
|
matches_ident: Ident,
|
||||||
body: Expr,
|
body: Expr,
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ pub struct MutApp {
|
|||||||
pub struct RunCliArgs {
|
pub struct RunCliArgs {
|
||||||
command: Path,
|
command: Path,
|
||||||
mut_app: Option<MutApp>,
|
mut_app: Option<MutApp>,
|
||||||
make_seed: Option<MakeSeed>,
|
make_ctx: Option<MakeCtx>,
|
||||||
exit_fn: Option<Expr>,
|
exit_fn: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ use syn::parse::{Parse, ParseStream};
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl Parse for MakeSeed {
|
impl Parse for MakeCtx {
|
||||||
fn parse(input: ParseStream) -> Result<Self> {
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
let matches_ident = input.parse()?;
|
let matches_ident = input.parse()?;
|
||||||
let _: token::FatArrow = input.parse()?;
|
let _: token::FatArrow = input.parse()?;
|
||||||
let body = input.parse()?;
|
let body = input.parse()?;
|
||||||
Ok(MakeSeed {
|
Ok(MakeCtx {
|
||||||
matches_ident,
|
matches_ident,
|
||||||
body,
|
body,
|
||||||
})
|
})
|
||||||
@@ -37,7 +37,7 @@ impl Parse for RunCliArgs {
|
|||||||
if !input.is_empty() {
|
if !input.is_empty() {
|
||||||
let _: token::Comma = input.parse()?;
|
let _: token::Comma = input.parse()?;
|
||||||
}
|
}
|
||||||
let make_seed = if !input.is_empty() {
|
let make_ctx = if !input.is_empty() {
|
||||||
Some(input.parse()?)
|
Some(input.parse()?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -53,7 +53,7 @@ impl Parse for RunCliArgs {
|
|||||||
Ok(RunCliArgs {
|
Ok(RunCliArgs {
|
||||||
command,
|
command,
|
||||||
mut_app,
|
mut_app,
|
||||||
make_seed,
|
make_ctx,
|
||||||
exit_fn,
|
exit_fn,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,14 +26,4 @@ pub trait Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SeedableContext<T: Clone>: Context {
|
|
||||||
fn new(seed: T) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Context for () {}
|
impl Context for () {}
|
||||||
|
|
||||||
impl<T: Copy> SeedableContext<T> for () {
|
|
||||||
fn new(_: T) -> Self {
|
|
||||||
()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,20 +20,20 @@
|
|||||||
///
|
///
|
||||||
/// See also: [arg](rpc_toolkit_macro::arg), [context](rpc_toolkit_macro::context)
|
/// See also: [arg](rpc_toolkit_macro::arg), [context](rpc_toolkit_macro::context)
|
||||||
pub use rpc_toolkit_macro::command;
|
pub use rpc_toolkit_macro::command;
|
||||||
/// `rpc_server!(command, seed, status_fn)`
|
/// `rpc_server!(command, context, status_fn)`
|
||||||
/// - returns: [Server](hyper::Server)
|
/// - returns: [Server](hyper::Server)
|
||||||
/// - `command`: path to an rpc command (with the `#[command]` attribute)
|
/// - `command`: path to an rpc command (with the `#[command]` attribute)
|
||||||
/// - `seed`: A seed for the [SeedableContext] of the rpc command.
|
/// - `context`: The [Context] for `command`. Must implement [Clone](std::clone::Clone).
|
||||||
/// - `status_fn` (optional): a function that takes a JSON RPC error code (`i32`) and returns a [StatusCode](hyper::StatusCode)
|
/// - `status_fn` (optional): a function that takes a JSON RPC error code (`i32`) and returns a [StatusCode](hyper::StatusCode)
|
||||||
/// - default: `|_| StatusCode::OK`
|
/// - default: `|_| StatusCode::OK`
|
||||||
pub use rpc_toolkit_macro::rpc_server;
|
pub use rpc_toolkit_macro::rpc_server;
|
||||||
/// `run_cli!(command, app_mutator, make_seed, exit_fn)`
|
/// `run_cli!(command, app_mutator, make_ctx, exit_fn)`
|
||||||
/// - this function does not return
|
/// - this function does not return
|
||||||
/// - `command`: path to an rpc command (with the `#[command]` attribute)
|
/// - `command`: path to an rpc command (with the `#[command]` attribute)
|
||||||
/// - `app_mutator` (optional): an expression that returns a mutated app.
|
/// - `app_mutator` (optional): an expression that returns a mutated app.
|
||||||
/// - example: `app => app.arg(Arg::with_name("port").long("port"))`
|
/// - example: `app => app.arg(Arg::with_name("port").long("port"))`
|
||||||
/// - default: `app => app`
|
/// - default: `app => app`
|
||||||
/// - `make_seed` (optional): an expression that takes [&ArgMatches](clap::ArgMatches) and returns a seed.
|
/// - `make_ctx` (optional): an expression that takes [&ArgMatches](clap::ArgMatches) and returns the [Context] used by `command`.
|
||||||
/// - example: `matches => matches.value_of("port")`
|
/// - example: `matches => matches.value_of("port")`
|
||||||
/// - default: `matches => matches`
|
/// - default: `matches => matches`
|
||||||
/// - `exit_fn` (optional): a function that takes a JSON RPC error code (`i32`) and returns an Exit code (`i32`)
|
/// - `exit_fn` (optional): a function that takes a JSON RPC error code (`i32`) and returns an Exit code (`i32`)
|
||||||
@@ -41,7 +41,7 @@ pub use rpc_toolkit_macro::rpc_server;
|
|||||||
pub use rpc_toolkit_macro::run_cli;
|
pub use rpc_toolkit_macro::run_cli;
|
||||||
pub use {clap, hyper, reqwest, serde, serde_json, tokio, url, yajrc};
|
pub use {clap, hyper, reqwest, serde, serde_json, tokio, url, yajrc};
|
||||||
|
|
||||||
pub use crate::context::{Context, SeedableContext};
|
pub use crate::context::Context;
|
||||||
|
|
||||||
pub mod command_helpers;
|
pub mod command_helpers;
|
||||||
mod context;
|
mod context;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use serde_json::Value;
|
|||||||
use url::Host;
|
use url::Host;
|
||||||
use yajrc::{AnyRpcMethod, GenericRpcMethod, Id, RpcError, RpcRequest, RpcResponse};
|
use yajrc::{AnyRpcMethod, GenericRpcMethod, Id, RpcError, RpcRequest, RpcResponse};
|
||||||
|
|
||||||
use crate::SeedableContext;
|
use crate::Context;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
#[cfg(feature = "cbor")]
|
#[cfg(feature = "cbor")]
|
||||||
@@ -20,10 +20,7 @@ lazy_static! {
|
|||||||
serde_json::to_vec(&RpcResponse::<AnyRpcMethod<'static>>::from(yajrc::INTERNAL_ERROR)).unwrap();
|
serde_json::to_vec(&RpcResponse::<AnyRpcMethod<'static>>::from(yajrc::INTERNAL_ERROR)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_builder<Ctx: SeedableContext<Seed>, Seed: Clone>(
|
pub fn make_builder<Ctx: Context>(ctx: &Ctx) -> (Builder<AddrIncoming>, PhantomData<Ctx>) {
|
||||||
seed: Seed,
|
|
||||||
) -> (Builder<AddrIncoming>, PhantomData<Ctx>) {
|
|
||||||
let ctx = Ctx::new(seed);
|
|
||||||
let addr = match ctx.host() {
|
let addr = match ctx.host() {
|
||||||
Host::Ipv4(ip) => (ip, ctx.port()).into(),
|
Host::Ipv4(ip) => (ip, ctx.port()).into(),
|
||||||
Host::Ipv6(ip) => (ip, ctx.port()).into(),
|
Host::Ipv6(ip) => (ip, ctx.port()).into(),
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ use url::Host;
|
|||||||
use yajrc::RpcError;
|
use yajrc::RpcError;
|
||||||
|
|
||||||
pub use crate as rpc_toolkit;
|
pub use crate as rpc_toolkit;
|
||||||
use crate::{command, rpc_server, Context, SeedableContext};
|
use crate::{command, rpc_server, Context};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub struct AppState<T, U> {
|
pub struct AppState<T, U> {
|
||||||
seed: T,
|
seed: T,
|
||||||
data: U,
|
data: U,
|
||||||
@@ -29,14 +30,6 @@ pub struct ConfigSeed {
|
|||||||
port: u16,
|
port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeedableContext<Arc<ConfigSeed>> for AppState<Arc<ConfigSeed>, ()> {
|
|
||||||
fn new(seed: Arc<ConfigSeed>) -> Self {
|
|
||||||
AppState {
|
|
||||||
seed: seed.clone(),
|
|
||||||
data: (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> Context for AppState<Arc<ConfigSeed>, T> {
|
impl<T> Context for AppState<Arc<ConfigSeed>, T> {
|
||||||
fn host(&self) -> Host<&str> {
|
fn host(&self) -> Host<&str> {
|
||||||
match &self.seed.host {
|
match &self.seed.host {
|
||||||
@@ -104,7 +97,7 @@ async fn test() {
|
|||||||
host: Host::parse("localhost").unwrap(),
|
host: Host::parse("localhost").unwrap(),
|
||||||
port: 8000,
|
port: 8000,
|
||||||
});
|
});
|
||||||
let server = rpc_server!(dothething::<String, _>, seed);
|
let server = rpc_server!(dothething::<String, _>, AppState { seed, data: () });
|
||||||
let handle = tokio::spawn(server);
|
let handle = tokio::spawn(server);
|
||||||
let mut cmd = tokio::process::Command::new("cargo")
|
let mut cmd = tokio::process::Command::new("cargo")
|
||||||
.arg("test")
|
.arg("test")
|
||||||
@@ -158,7 +151,7 @@ fn cli_test() {
|
|||||||
port: 8000,
|
port: 8000,
|
||||||
});
|
});
|
||||||
dothething::cli_handler::<String, _, _>(
|
dothething::cli_handler::<String, _, _>(
|
||||||
SeedableContext::new(seed),
|
AppState { seed, data: () },
|
||||||
None,
|
None,
|
||||||
&matches,
|
&matches,
|
||||||
"".into(),
|
"".into(),
|
||||||
@@ -175,10 +168,10 @@ fn cli_example() {
|
|||||||
app => app
|
app => app
|
||||||
.arg(Arg::with_name("host").long("host").short("h").takes_value(true))
|
.arg(Arg::with_name("host").long("host").short("h").takes_value(true))
|
||||||
.arg(Arg::with_name("port").long("port").short("p").takes_value(true)),
|
.arg(Arg::with_name("port").long("port").short("p").takes_value(true)),
|
||||||
matches => Arc::new(ConfigSeed {
|
matches => AppState { seed: Arc::new(ConfigSeed {
|
||||||
host: Host::parse(matches.value_of("host").unwrap_or("localhost")).unwrap(),
|
host: Host::parse(matches.value_of("host").unwrap_or("localhost")).unwrap(),
|
||||||
port: matches.value_of("port").unwrap_or("8000").parse().unwrap(),
|
port: matches.value_of("port").unwrap_or("8000").parse().unwrap(),
|
||||||
}),
|
}), data: () },
|
||||||
|code| if code < 0 { 1 } else { code }
|
|code| if code < 0 { 1 } else { code }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user