//! # Simple example server //! //! Run this example with `cargo run --example server --features server`. It will listen on //! for incoming XML-RPC requests. //! //! Testing this local server is straightforward, either with the included `client` example, or //! with three lines of python: //! //! ```python3 //! >>> import xmlrpc.client //! >>> proxy = xmlrpc.client.ServerProxy("http://0.0.0.0:3000/") //! >>> proxy.hello("DXR") //! 'Handler type says: Hello, DXR!' //! >>> proxy.countme() //! 0 //! >>> proxy.countme() //! 1 //! >>> proxy.countme() //! 2 //! >>> proxy.add(1, 2) //! 3 //! ``` use std::sync::RwLock; use dxr::server::{async_trait, Handler, HandlerFn, HandlerResult}; use dxr::server_axum::{axum::http::HeaderMap, RouteBuilder, Server}; use dxr::{TryFromParams, TryToValue, Value}; struct CounterHandler { counter: RwLock, } impl CounterHandler { fn new(init: u32) -> CounterHandler { CounterHandler { counter: RwLock::new(init), } } } #[async_trait] impl Handler for CounterHandler { async fn handle(&self, _params: &[Value], _headers: HeaderMap) -> HandlerResult { let mut value = self.counter.write().unwrap(); let result = (*value as i32).try_to_value()?; *value += 1; Ok(result) } } fn hello_handler(params: &[Value], _headers: HeaderMap) -> HandlerResult { let name = String::try_from_params(params)?; Ok(format!("Handler function says: Hello, {name}!").try_to_value()?) } fn adder_handler(params: &[Value], _headers: HeaderMap) -> HandlerResult { let (a, b): (i32, i32) = TryFromParams::try_from_params(params)?; Ok((a + b).try_to_value()?) } #[tokio::main] async fn main() { let counter_handler = CounterHandler::new(0); let route = RouteBuilder::new() .set_path("/") .add_method("hello", Box::new(hello_handler as HandlerFn)) .add_method("countme", Box::new(counter_handler)) .add_method("add", Box::new(adder_handler as HandlerFn)) .build(); let server = Server::from_route("0.0.0.0:3000".parse().unwrap(), route); server.serve().await.expect("Failed to run server.") }