#[macro_use] extern crate log; #[macro_use] extern crate lazy_static; use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest}; use parking_lot::Mutex; use actix_web::web::{service, scope}; use actix_web::http::StatusCode; use std::sync::atomic::{AtomicUsize, Ordering}; use std::path::{PathBuf, Path}; use actix_web_static_files; use tera::Tera; use include_dir::Dir; use std::sync::Arc; use log::LevelFilter; mod tera_ext; // Embed static files include!(concat!(env!("OUT_DIR"), "/static_files.rs")); // Embed templates static TEMPLATES: include_dir::Dir = include_dir::include_dir!("./resources/templates"); lazy_static! { static ref TERA : Tera = { let mut tera = Tera::default(); tera_ext::tera_includedir_walk_folder(&mut tera, &TEMPLATES); tera }; } struct VisitCounter { pub counter : AtomicUsize, } impl VisitCounter { pub fn count_visit(&self) -> usize { self.counter.fetch_add(1, Ordering::Relaxed) } } #[get("/")] async fn service_index(req: HttpRequest, visits : web::Data) -> actix_web::Result { let mut context = tera::Context::new(); context.insert("visits", &visits.count_visit()); let html = TERA.render("index", &context).map_err(|e| { actix_web::error::ErrorInternalServerError(e) })?; Ok(HttpResponse::Ok().body(html)) } #[actix_web::main] async fn main() -> std::io::Result<()> { simple_logging::log_to_stderr(LevelFilter::Debug); let counter = web::Data::new(VisitCounter { counter : Default::default() }); HttpServer::new(move || { let static_files = actix_web_static_files::ResourceFiles::new("/static", included_static_files()) .do_not_resolve_defaults(); App::new() .app_data(counter.clone()) .service(service_index) .service(static_files) }) .bind("127.0.0.1:8080")?.run().await }