use std::sync::Arc;
use typeway::prelude::*;
typeway_path!(type HelloPath = "hello");
typeway_path!(type AddPath = "add" / u32 / u32);
type API = (GetEndpoint<HelloPath, String>, GetEndpoint<AddPath, String>);
async fn hello() -> Json<String> {
Json("Hello from Typeway!".to_string())
}
async fn add(path: Path<AddPath>) -> Json<String> {
let (a, b) = path.0;
Json(format!("{a} + {b} = {}", a + b))
}
#[tokio::main]
async fn main() {
let server = Server::<API>::new((bind::<_, _, _>(hello), bind::<_, _, _>(add)));
let router = Arc::new(server.into_router());
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let port = listener.local_addr().unwrap().port();
tokio::spawn({
let router = router.clone();
async move {
loop {
let (stream, _) = listener.accept().await.unwrap();
let io = hyper_util::rt::TokioIo::new(stream);
let router = router.clone();
tokio::spawn(async move {
let svc = hyper::service::service_fn(move |req| {
let router = router.clone();
async move { Ok::<_, std::convert::Infallible>(router.route(req).await) }
});
let _ = hyper::server::conn::http1::Builder::new()
.serve_connection(io, svc)
.await;
});
}
}
});
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
let client = Client::new(&format!("http://127.0.0.1:{port}")).unwrap();
type HelloEndpoint = GetEndpoint<HelloPath, String>;
type AddEndpoint = GetEndpoint<AddPath, String>;
let greeting = client.call::<HelloEndpoint>(()).await.unwrap();
println!("GET /hello => {greeting}");
let sum = client.call::<AddEndpoint>((3u32, 7u32)).await.unwrap();
println!("GET /add/3/7 => {sum}");
println!("\nBoth calls were fully type-checked at compile time!");
}