use anyhow::Context; use askama::Template; use axum::{ http::StatusCode, response::{Html, IntoResponse, Response}, routing::get, Router, }; use tower_http::services::ServeDir; use tracing::info; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; pub async fn run() -> anyhow::Result<()> { tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| "achubb_backend".into()), ) .with(tracing_subscriber::fmt::layer()) .init(); info!("initializing router..."); let assets_path = std::env::current_dir().unwrap(); let port = 8000_u16; let addr = std::net::SocketAddr::from(([0, 0, 0, 0], port)); let api_router = Router::new().route("/hello", get(hello_from_the_server)); let router = Router::new() .nest("/api", api_router) .route("/", get(hello)) .route("/another-page", get(another_page)) .nest_service( "/assets", ServeDir::new(format!("{}/assets", assets_path.to_str().unwrap())), ); info!("router initialized, now listening on port {}", port); axum::Server::bind(&addr) .serve(router.into_make_service()) .await .context("error while starting server")?; Ok(()) } async fn hello() -> impl IntoResponse { let template = HelloTemplate {}; HtmlTemplate(template) } #[derive(Template)] #[template(path = "hello.html")] struct HelloTemplate; /// A wrapper type that we'll use to encapsulate HTML parsed by askama into valid HTML for axum to serve. struct HtmlTemplate(T); /// Allows us to convert Askama HTML templates into valid HTML for axum to serve in the response. impl IntoResponse for HtmlTemplate where T: Template, { fn into_response(self) -> Response { // Attempt to render the template with askama match self.0.render() { // If we're able to successfully parse and aggregate the template, serve it Ok(html) => Html(html).into_response(), // If we're not, return an error or some bit of fallback HTML Err(err) => ( StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to render template. Error: {}", err), ) .into_response(), } } } async fn another_page() -> impl IntoResponse { let template = AnotherPageTemplate {}; HtmlTemplate(template) } #[derive(Template)] #[template(path = "another-page.html")] struct AnotherPageTemplate; async fn hello_from_the_server() -> &'static str { "Hello!" }