Skip to content

Commit cc81cb9

Browse files
committed
feat: Update Dispatcher to use the Resource trait
1 parent 3a8879e commit cc81cb9

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

src/lib.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ It is basically a HTTP toolkit for building HTTP-friendly applications using the
1010
Webmachine-rust works with Hyper and sits between the Hyper Handler and your application code. It provides a resource struct
1111
with callbacks to handle the decisions required as the state machine is executed against the request with the following sequence.
1212
13-
REQUEST -> Hyper Handler -> WebmachineDispatcher -> WebmachineResource -> Your application code -> WebmachineResponse -> Hyper -> RESPONSE
13+
REQUEST -> Hyper Handler -> WebmachineDispatcher -> Resource -> Your application code -> WebmachineResponse -> Hyper -> RESPONSE
1414
1515
## Features
1616
1717
- Handles the hard parts of content negotiation, conditional requests, and response codes for you.
18-
- Provides a resource struct with points of extension to let you describe what is relevant about your particular resource.
18+
- Provides a resource trait and struct with points of extension to let you describe what is relevant about your particular resource.
1919
2020
## Missing Features
2121
@@ -30,14 +30,19 @@ This implementation has the following deficiencies:
3030
3131
- Automatically decoding request bodies and encoding response bodies.
3232
- No easy mechanism to generate bodies with different content types (e.g. JSON vs. XML).
33-
- No easy mechanism for handling sub-paths in a resource.
3433
- Dynamically determining the methods allowed on the resource.
3534
3635
## Getting started with Hyper
3736
3837
Follow the getting started documentation from the Hyper crate to setup a Hyper service for your server.
39-
You need to define a WebmachineDispatcher that maps resource paths to your webmachine resources (WebmachineResource).
40-
Each WebmachineResource defines all the callbacks (via Closures) and values required to implement a resource.
38+
39+
There are two ways of using this crate. You can either use the `WebmachineResource` struct and add callbacks
40+
for the state you need to modify, or you can create your own resource structs and implement the
41+
`Resource` trait.
42+
43+
You need to define a WebmachineDispatcher that maps resource paths to your webmachine resources
44+
(WebmachineResource or structs that implement Resource). WebmachineResource defines all the callbacks
45+
(via Closures) and values required to implement a resource.
4146
4247
Note: This example uses the maplit crate to provide the `btreemap` macro and the log crate for the logging macros.
4348
@@ -70,7 +75,7 @@ Note: This example uses the maplit crate to provide the `btreemap` macro and the
7075
// use it in the loop below.
7176
let dispatcher = Arc::new(WebmachineDispatcher {
7277
routes: btreemap!{
73-
"/myresource" => WebmachineResource {
78+
"/myresource" => WebmachineDispatcher::box_resource(WebmachineResource {
7479
// Methods allowed on this resource
7580
allowed_methods: owned_vec(&["OPTIONS", "GET", "HEAD", "POST"]),
7681
// if the resource exists callback
@@ -86,7 +91,7 @@ Note: This example uses the maplit crate to provide the `btreemap` macro and the
8691
process_post: async_callback(|_, _| /* Handle the post here */ ready(Ok(true)).boxed() ),
8792
// default everything else
8893
.. WebmachineResource::default()
89-
}
94+
})
9095
}
9196
});
9297
@@ -1495,7 +1500,7 @@ fn generate_http_response(context: &WebmachineContext) -> http::Result<Response<
14951500
/// The main hyper dispatcher
14961501
pub struct WebmachineDispatcher {
14971502
/// Map of routes to webmachine resources
1498-
pub routes: BTreeMap<&'static str, WebmachineResource>
1503+
pub routes: BTreeMap<&'static str, Box<dyn Resource + Send + Sync>>
14991504
}
15001505

15011506
impl WebmachineDispatcher {
@@ -1524,8 +1529,9 @@ impl WebmachineDispatcher {
15241529
.collect()
15251530
}
15261531

1527-
fn lookup_resource(&self, path: &str) -> Option<&WebmachineResource> {
1532+
fn lookup_resource(&self, path: &str) -> Option<&(dyn Resource + Send + Sync)> {
15281533
self.routes.get(path)
1534+
.map(|resource| resource.as_ref())
15291535
}
15301536

15311537
/// Dispatches to the matching webmachine resource. If there is no matching resource, returns
@@ -1549,6 +1555,11 @@ impl WebmachineDispatcher {
15491555
None => context.response.status = 404
15501556
};
15511557
}
1558+
1559+
/// Convenience function to box a resource
1560+
pub fn box_resource<R: Resource + Send + Sync + 'static>(resource: R) -> Box<dyn Resource + Send + Sync> {
1561+
Box::new(resource)
1562+
}
15521563
}
15531564

15541565
#[cfg(test)]

src/tests.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ fn resource(path: &str) -> WebmachineRequest {
3232
fn path_matcher_test() {
3333
let dispatcher = WebmachineDispatcher {
3434
routes: btreemap! {
35-
"/" => WebmachineResource::default(),
36-
"/path1" => WebmachineResource::default(),
37-
"/path2" => WebmachineResource::default(),
38-
"/path1/path3" => WebmachineResource::default(),
39-
"/path2/{id}" => WebmachineResource::default(),
40-
"/path2/{id}/path3" => WebmachineResource::default()
35+
"/" => WebmachineDispatcher::box_resource(WebmachineResource::default()),
36+
"/path1" => WebmachineDispatcher::box_resource(WebmachineResource::default()),
37+
"/path2" => WebmachineDispatcher::box_resource(WebmachineResource::default()),
38+
"/path1/path3" => WebmachineDispatcher::box_resource(WebmachineResource::default()),
39+
"/path2/{id}" => WebmachineDispatcher::box_resource(WebmachineResource::default()),
40+
"/path2/{id}/path3" => WebmachineDispatcher::box_resource(WebmachineResource::default())
4141
}
4242
};
4343

@@ -105,7 +105,7 @@ fn sanitise_path_test() {
105105
async fn dispatcher_returns_404_if_there_is_no_matching_resource() {
106106
let mut context = WebmachineContext::default();
107107
let displatcher = WebmachineDispatcher {
108-
routes: btreemap! { "/some/path" => WebmachineResource::default() }
108+
routes: btreemap! { "/some/path" => WebmachineDispatcher::box_resource(WebmachineResource::default()) }
109109
};
110110
displatcher.dispatch_to_resource(&mut context).await;
111111
expect(context.response.status).to(be_equal_to(404));

0 commit comments

Comments
 (0)