use poem::{
listener::TcpListener, Endpoint, IntoResponse, Request, Response, Result, Route, Server,
};
#[derive(clap::Parser)]
pub struct Options {
#[clap(long, env = "HOST", default_value = "127.0.0.1")]
host: String,
#[clap(short = 'p', long, env = "PORT", default_value = "8080")]
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("*", Hello(Some("world".to_string())));
dbg!(self.url());
Ok(Server::new(TcpListener::bind(self.addr()))
.name("Hello")
.run(app)
.await?)
}
}
#[derive(Clone)]
pub struct Hello(Option<String>);
impl IntoResponse for Hello {
fn into_response(self) -> Response {
let msg = match self.0 {
Some(name) => format!("hello {}", name),
None => format!("hello"),
};
msg.into_response()
}
}
impl Endpoint for Hello {
type Output = Self;
async fn call(&self, req: Request) -> Result<Self::Output> {
let path = req.uri().path();
let res = match path {
"/" => self.clone(),
_ => Hello(Some(path[1..].to_string())),
};
Ok(res)
}
}