tower_type_steer

Crates.iotower_type_steer
lib.rstower_type_steer
version0.1.0
sourcesrc
created_at2024-10-05 09:20:37.592284
updated_at2024-10-05 09:20:37.592284
descriptionSteer (aka route, aka dispatch) request to service based on their types.
homepage
repositoryhttps://github.com/krtab/tower_type_steer
max_upload_size
id1397535
size15,303
Arthur Carcano (krtab)

documentation

README

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:?}");
}
Commit count: 2

cargo fmt