use gdbg::dbg; use poem::{handler, listener::TcpListener, web::Json, Request, Route, Server}; use querystring::querify; use serde::Serialize; use std::collections::BTreeMap; #[derive(clap::Parser)] pub struct Options { #[clap(long, env = "HOST", default_value = "127.0.0.1")] /// Set host host: String, #[clap(short = 'p', long, env = "PORT", default_value = "8080")] /// Set listening port port: String, } impl Options { fn host(&self) -> String { self.host.clone() } fn port(&self) -> String { self.port.clone() } fn hostport(&self) -> String { format!("{}:{}", self.host(), self.port()) } fn url(&self) -> String { format!("http://{}", self.hostport()) } fn addr(&self) -> std::net::SocketAddr { self.hostport().parse().unwrap() } pub async fn run(&mut self) -> Result<(), anyhow::Error> { let app = Route::new().at("*", echo); dbg!(self.url()); Ok(Server::new(TcpListener::bind(self.addr())) .name("hello") .run(app) .await?) } } #[derive(Debug, Serialize)] pub struct Response { method: String, path: String, query: String, headers: BTreeMap>, values: BTreeMap>, } pub fn echo_impl(req: &Request) -> Response { let method = req.method().to_string(); let path = req.uri().path().to_string(); let query = req.uri().query().unwrap_or("").to_string(); let headers = req .headers() .iter() .map(|(name, value)| { ( name.as_str().to_string(), value.to_str().unwrap().to_string(), ) }) .fold( BTreeMap::>::new(), |mut acc: BTreeMap<_, _>, (left, right)| { acc.entry(left) .and_modify(|values| values.push(right.clone())) .or_insert(vec![right]); acc }, ); dbg!(querify(&query)); let values = querify(&query) .iter() .map(|(name, value)| (name.to_string(), value.to_string())) .fold( BTreeMap::>::new(), |mut acc: BTreeMap<_, _>, (left, right)| { dbg!((&left, &right)); acc.entry(left) .and_modify(|values| values.push(right.clone())) .or_insert(vec![right]); acc }, ); Response { method, path, query, headers, values, } } #[handler] pub fn echo(req: &Request) -> Json { Json(echo_impl(req)) }