Skip to content

Commit be5eb2b

Browse files
committed
Update sync code to support Context<T>.
1 parent 1b1c4b8 commit be5eb2b

File tree

3 files changed

+77
-46
lines changed

3 files changed

+77
-46
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "json-rpc2"
3-
version = "0.5.3"
3+
version = "0.6.0"
44
authors = ["muji <[email protected]>"]
55
edition = "2018"
66
description = "Simple, robust and pragmatic JSON-RPC 2.0 implementation"

examples/hello-world.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ use json_rpc2::*;
22
use serde_json::Value;
33

44
struct ServiceHandler;
5-
impl Service for ServiceHandler {
6-
fn handle(&self, req: &mut Request) -> Result<Option<Response>> {
5+
impl<T> Service<T> for ServiceHandler {
6+
fn handle(&self, request: &mut Request, _context: &Context<T>) -> Result<Option<Response>> {
77
let mut response = None;
8-
if req.matches("hello") {
9-
let params: String = req.deserialize()?;
8+
if request.matches("hello") {
9+
let params: String = request.deserialize()?;
1010
let message = format!("Hello, {}!", params);
11-
response = Some((req, Value::String(message)).into());
11+
response = Some((request, Value::String(message)).into());
1212
}
1313
Ok(response)
1414
}
1515
}
1616

1717
fn main() -> Result<()> {
18-
let service: Box<dyn Service> = Box::new(ServiceHandler {});
18+
let service: Box<dyn Service<()>> = Box::new(ServiceHandler {});
1919
let mut request = Request::new("hello", Some(Value::String("world".to_string())));
2020
let services = vec![&service];
2121
let response = serve(&services, &mut request);

src/lib.rs

+70-39
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
//! use serde_json::Value;
77
//!
88
//! struct ServiceHandler;
9-
//! impl Service for ServiceHandler {
10-
//! fn handle(&self, req: &mut Request) -> Result<Option<Response>> {
9+
//! impl<T> Service<T> for ServiceHandler {
10+
//! fn handle(&self, request: &mut Request, context: &Context<T>) -> Result<Option<Response>> {
1111
//! let mut response = None;
12-
//! if req.matches("hello") {
13-
//! let params: String = req.deserialize()?;
12+
//! if request.matches("hello") {
13+
//! let params: String = request.deserialize()?;
1414
//! let message = format!("Hello, {}!", params);
15-
//! response = Some((req, Value::String(message)).into());
15+
//! response = Some((request, Value::String(message)).into());
1616
//! }
1717
//! Ok(response)
1818
//! }
1919
//! }
2020
//!
2121
//! fn main() -> Result<()> {
22-
//! let service: Box<dyn Service> = Box::new(ServiceHandler {});
22+
//! let service: Box<dyn Service<()>> = Box::new(ServiceHandler {});
2323
//! let mut request = Request::new(
2424
//! "hello", Some(Value::String("world".to_string())));
2525
//! let services = vec![&service];
@@ -174,44 +174,75 @@ pub struct RpcError {
174174
}
175175

176176
/// Trait for services that maybe handle a request.
177-
pub trait Service {
177+
pub trait Service<T> {
178178
/// Service implementations are invoked with a request
179179
/// and should reply with a response if the method name
180180
/// is one handled by the service.
181181
///
182182
/// If the method name for the request is not handled by the service
183183
/// if should return `None`.
184-
fn handle(&self, req: &mut Request) -> Result<Option<Response>>;
184+
fn handle(&self, request: &mut Request, context: &Context<T>) -> Result<Option<Response>>;
185185
}
186186

187-
/// Call services in order and return the first response message.
188-
///
189-
/// If no services match the incoming request this will
190-
/// return a `Error::MethodNotFound`.
191-
pub fn handle<'a>(
192-
services: &'a Vec<&'a Box<dyn Service>>,
193-
request: &mut Request,
194-
) -> Result<Response> {
195-
for service in services {
196-
if let Some(result) = service.handle(request)? {
197-
return Ok(result);
187+
/// Context information passed to service handlers that wraps type `T`.
188+
#[derive(Default)]
189+
pub struct Context<T> {
190+
/// Inner context data.
191+
pub data: T,
192+
}
193+
194+
/// Serve requests.
195+
pub struct Server<'a, T> {
196+
/// Services that the server should invoke for every request.
197+
pub services: &'a Vec<&'a Box<dyn Service<T>>>,
198+
}
199+
200+
impl<'a, T> Server<'a, T> {
201+
/// Call services in order and return the first response message.
202+
///
203+
/// If no services match the incoming request this will
204+
/// return a `Error::MethodNotFound`.
205+
pub(crate) fn handle(
206+
&self,
207+
request: &mut Request,
208+
context: &Context<T>,
209+
) -> Result<Response> {
210+
for service in self.services {
211+
if let Some(result) = service.handle(request, context)? {
212+
return Ok(result);
213+
}
198214
}
199-
}
200215

201-
let err = Error::MethodNotFound {
202-
name: request.method().to_string(),
203-
id: request.id.clone(),
204-
};
216+
let err = Error::MethodNotFound {
217+
name: request.method().to_string(),
218+
id: request.id.clone(),
219+
};
220+
221+
Ok((request, err).into())
222+
}
205223

206-
Ok((request, err).into())
224+
/// Infallible service handler, errors are automatically converted to responses.
225+
pub fn serve(
226+
&self,
227+
request: &mut Request,
228+
context: &Context<T>,
229+
) -> Response {
230+
match self.handle(request, context) {
231+
Ok(response) => response,
232+
Err(e) => e.into(),
233+
}
234+
}
207235
}
208236

209-
/// Infallible service handler, errors are automatically converted to responses.
237+
/// Create a server and call services with a context of `()`.
210238
pub fn serve<'a>(
211-
services: &'a Vec<&'a Box<dyn Service>>,
239+
services: &'a Vec<&'a Box<dyn Service<()>>>,
212240
request: &mut Request,
213241
) -> Response {
214-
match handle(services, request) {
242+
let server = Server { services };
243+
//let data = ();
244+
let context = Context {data: ()};
245+
match server.handle(request, &context) {
215246
Ok(response) => response,
216247
Err(e) => e.into(),
217248
}
@@ -391,29 +422,29 @@ mod test {
391422
}
392423

393424
struct HelloServiceHandler;
394-
impl Service for HelloServiceHandler {
395-
fn handle(&self, req: &mut Request) -> Result<Option<Response>> {
425+
impl<T> Service<T> for HelloServiceHandler {
426+
fn handle(&self, request: &mut Request, _context: &Context<T>) -> Result<Option<Response>> {
396427
let mut response = None;
397-
if req.matches("hello") {
398-
let params: String = req.deserialize()?;
428+
if request.matches("hello") {
429+
let params: String = request.deserialize()?;
399430
let message = format!("Hello, {}!", params);
400-
response = Some((req, Value::String(message)).into());
431+
response = Some((request, Value::String(message)).into());
401432
}
402433
Ok(response)
403434
}
404435
}
405436

406437
struct InternalErrorService;
407-
impl Service for InternalErrorService {
408-
fn handle(&self, _req: &mut Request) -> Result<Option<Response>> {
438+
impl<T> Service<T> for InternalErrorService {
439+
fn handle(&self, _request: &mut Request, _context: &Context<T>) -> Result<Option<Response>> {
409440
// Must Box the error as it is foreign.
410441
Err(Error::boxed(MockError::Internal("Mock error".to_string())))
411442
}
412443
}
413444

414445
#[test]
415446
fn jsonrpc_service_ok() -> Result<()> {
416-
let service: Box<dyn Service> = Box::new(HelloServiceHandler {});
447+
let service: Box<dyn Service<()>> = Box::new(HelloServiceHandler {});
417448
let mut request = Request::new("hello", Some(Value::String("world".to_string())));
418449
let services = vec![&service];
419450
let response = serve(&services, &mut request);
@@ -444,7 +475,7 @@ mod test {
444475

445476
#[test]
446477
fn jsonrpc_service_method_not_found() -> Result<()> {
447-
let service: Box<dyn Service> = Box::new(HelloServiceHandler {});
478+
let service: Box<dyn Service<()>> = Box::new(HelloServiceHandler {});
448479
let mut request = Request::new("non-existent", None);
449480
let services = vec![&service];
450481
let response = serve(&services, &mut request);
@@ -461,7 +492,7 @@ mod test {
461492

462493
#[test]
463494
fn jsonrpc_invalid_params() -> Result<()> {
464-
let service: Box<dyn Service> = Box::new(HelloServiceHandler {});
495+
let service: Box<dyn Service<()>> = Box::new(HelloServiceHandler {});
465496
let mut request = Request::new("hello", Some(Value::Bool(true)));
466497
let services = vec![&service];
467498
let response = serve(&services, &mut request);
@@ -478,7 +509,7 @@ mod test {
478509

479510
#[test]
480511
fn jsonrpc_internal_error() -> Result<()> {
481-
let service: Box<dyn Service> = Box::new(InternalErrorService {});
512+
let service: Box<dyn Service<()>> = Box::new(InternalErrorService {});
482513
let mut request = Request::new("foo", None);
483514
let services = vec![&service];
484515
let response = serve(&services, &mut request);

0 commit comments

Comments
 (0)