// This file is part of Locus . // Copyright (C) 2022-2022 Fuwn // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 3. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // Copyright (C) 2022-2022 Fuwn // SPDX-License-Identifier: GPL-3.0-only #![feature(once_cell, is_some_with, const_extern_fn)] #![deny( warnings, nonstandard_style, unused, future_incompatible, rust_2018_idioms, unsafe_code )] #![deny(clippy::all, clippy::nursery, clippy::pedantic)] #![recursion_limit = "128"] #![allow(clippy::cast_precision_loss)] mod macros; mod modules; mod route; mod xml; #[macro_use] extern crate log; use std::{lazy::SyncLazy, sync::Mutex}; use pickledb::PickleDb; use tokio::time::Instant; const ERROR_HANDLER_RESPONSE: &str = "The requested resource could not be found at this time. You can try \ refreshing the page, if that doesn't change anything; contact Fuwn! \ (contact@fuwn.me)"; static DATABASE: SyncLazy> = SyncLazy::new(|| { Mutex::new({ if std::fs::File::open(".locus/locus.db").is_ok() { PickleDb::load_json( ".locus/locus.db", pickledb::PickleDbDumpPolicy::AutoDump, ) .unwrap() } else { PickleDb::new_json( ".locus/locus.db", pickledb::PickleDbDumpPolicy::AutoDump, ) } }) }); fn time_mounts(context: &str, timer: &mut Instant, mut mounter: T) where T: FnMut() { mounter(); info!( "{} mounts took {}ms", context, timer.elapsed().as_nanos() as f64 / 1_000_000.0 ); *timer = Instant::now(); } fn time_section(timer: &mut Instant, context: &str) { info!( "{} took {}ms", context, timer.elapsed().as_nanos() as f64 / 1_000_000.0 ); *timer = Instant::now(); } #[windmark::main] async fn main() -> Result<(), Box> { std::env::set_var("RUST_LOG", "windmark,locus=trace"); pretty_env_logger::init(); dotenv::dotenv().ok(); let mut time_mount = Instant::now(); let mut router = windmark::Router::new(); router.set_private_key_file(".locus/locus_private.pem"); router.set_certificate_file(".locus/locus_public.pem"); router.set_error_handler(Box::new(|_| { windmark::Response::NotFound(ERROR_HANDLER_RESPONSE.into()) })); router.set_fix_path(true); time_section(&mut time_mount, "creating router"); time_mounts("module", &mut time_mount, || stateless!(router, modules)); std::thread::spawn(modules::search::index); router.run().await }