use std::time::{Instant, SystemTime}; use anyhow::Context; use clap::Parser as _; use nara_core::BookContainer; use nara_slurper_1_12_infinity::Realm; use crate::{ cli::{Cli, Command, ServeArgs}, library::Library, web::start_webserver, }; use nara_slurper_1_12_world::slurp_world; pub mod cli; pub mod library; pub mod web; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); #[tokio::main] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let cli = Cli::parse(); match cli.command { Command::Serve(args) => { let library = build_library(&args).context("Building library")?; if args.start_webserver { start_webserver(&args, library) .await .context("Running webserver")?; } } Command::SlurpWorld(args) => match args.version { cli::MinecraftVersion::V1_12 => { let num_workers = args.workers.unwrap_or_else(|| { std::thread::available_parallelism() .map(|n| n.get()) .unwrap_or(4) }); let mut container = BookContainer::open_or_new(&args.container_path) .context("Opening container")?; let start = Instant::now(); let books = slurp_world(&args.world_path, num_workers) .await .context("Slurping world")?; let elapsed_ms = start.elapsed().as_secs_f64() * 1000.0; let total = books.len(); let dupes = books .into_iter() .filter(|b| !container.add(b.clone())) .count(); container .save(&args.container_path) .context("Saving container")?; tracing::info!( "Found {total} books, of which {dupes} were duplicates in {elapsed_ms:.3} ms" ); } }, Command::SlurpRealm(args) => match args.version { cli::MinecraftVersion::V1_12 => { let mut container = BookContainer::open_or_new(&args.container_path) .context("Opening container")?; let start = Instant::now(); let books = Realm::read(args.realm_path)?.slurp(); let elapsed_ms = start.elapsed().as_secs_f64() * 1000.0; let total = books.len(); let dupes = books .into_iter() .filter(|b| !container.add(b.clone())) .count(); container .save(&args.container_path) .context("Saving container")?; tracing::info!( "Found {total} books, of which {dupes} were duplicates in {elapsed_ms:.3} ms" ); } }, } Ok(()) } fn build_library(args: &ServeArgs) -> anyhow::Result { let start = SystemTime::now(); tracing::info!("Opening book container..."); let container = BookContainer::open_or_new(&args.container_path) .context("Opening container")?; tracing::info!( "Container opened, took {} ms. Building library...", SystemTime::now().duration_since(start)?.as_nanos() / 1_000_000 ); let start = SystemTime::now(); let mut library = Library::new( args.content_threshold, args.title_threshold, args.author_threshold, ); for book in container.books() { library.add_book( book.clone(), args.warn_empty, args.filter_empty_books, ); } tracing::info!( "Built library in {}ms", SystemTime::now().duration_since(start)?.as_nanos() / 1_000_000 ); Ok(library) }