ditch SeedableContext

This commit is contained in:
Aiden McClelland
2021-04-12 16:14:21 -06:00
parent fba286e7a8
commit b9676c591a
10 changed files with 34 additions and 54 deletions

View File

@@ -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,
) )

View File

@@ -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>,
} }

View File

@@ -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,
}) })
} }

View File

@@ -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

View File

@@ -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>,
} }

View File

@@ -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,
}) })
} }

View File

@@ -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 {
()
}
}

View File

@@ -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;

View File

@@ -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(),

View File

@@ -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 }
) )
} }