Crates.io | tower_type_steer |
lib.rs | tower_type_steer |
version | 0.1.0 |
source | src |
created_at | 2024-10-05 09:20:37.592284 |
updated_at | 2024-10-05 09:20:37.592284 |
description | Steer (aka route, aka dispatch) request to service based on their types. |
homepage | |
repository | https://github.com/krtab/tower_type_steer |
max_upload_size | |
id | 1397535 |
size | 15,303 |
Dispatch request to service by trying to convert to the service's request type.
use futures::future::ready;
use serde::Deserialize;
use tower::{service_fn, Service, ServiceBuilder, ServiceExt};
use tower_type_steer::Converter;
#[derive(Deserialize, Clone)]
struct Foo {
x: i8,
y: i8,
}
#[derive(Deserialize, Clone)]
struct Bar {
z: i8,
}
fn main() {
// impl Service<Foo>
let foo_service = service_fn(|foo: Foo| ready(foo.x.checked_add(foo.y).ok_or("Overflow")));
// impl Service<Bar>
let bar_service = service_fn(|bar: Bar| ready(Ok::<_, &'static str>(bar.z)));
let error_service = service_fn(|_: &str| ready(Err::<i8, _>("No matching json")));
let mut s = ServiceBuilder::new()
.layer(tower_type_steer::serde_conv::json().wrap(foo_service))
.layer(tower_type_steer::serde_conv::json().wrap(bar_service))
.service(error_service);
let res: Result<_, &str> = futures::executor::block_on(async move {
let s = s.ready().await?;
let res = [
// Ok(5) (foo_service)
s.call(r#"{"x": 3, "y": 2}"#).await,
// Err("Overflow") (foo_service)
s.call(r#"{"x": 120, "y": 120}"#).await,
// Err("Ok(2)") (bar_service)
s.call(r#"{"z": 2}"#).await,
// Err("No matching json") (error_service)
s.call(r#"{}"#).await,
];
Ok(res)
});
println!("{res:?}");
}