diff --git a/src/main.rs b/src/main.rs index 2fd083d..0bd4169 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use std::{ fmt::Write, + path::PathBuf, sync::{Arc, RwLock}, }; @@ -22,6 +23,22 @@ use validator::{Validate, ValidationError}; mod common; mod store; +#[derive(Debug, clap::Parser)] +/// Arbre +struct Cmd { + #[arg(short, long, default_value_t = 8200)] + /// Port on which th server will listen. + port: u16, + + #[arg(short, long, default_value = "0.0.0.0")] + /// Hostname or address on which th server will listen. + address: String, + + #[arg(short, long, default_value = "./store")] + /// Path to the directory to use as storage for topics. + store: PathBuf, +} + #[derive(Debug, Clone)] struct MainState { store: Arc>, @@ -29,7 +46,13 @@ struct MainState { #[tokio::main] async fn main() -> Result<()> { - let store = Store::open("./store")?; + let Cmd { + address, + port, + store, + } = clap::Parser::parse(); + + let store = Store::open(store)?; let store = Arc::new(RwLock::new(store)); let state = MainState { store }; @@ -42,7 +65,7 @@ async fn main() -> Result<()> { .route("/", get(home)) .with_state(state); - let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap(); + let listener = TcpListener::bind((address, port)).await.unwrap(); let server = axum::serve(listener, app); server.await?; diff --git a/src/store.rs b/src/store.rs index e86291d..76f1692 100644 --- a/src/store.rs +++ b/src/store.rs @@ -1,18 +1,18 @@ use std::{ fs::{self, OpenOptions}, io::{ErrorKind, Write}, + path::PathBuf, }; use anyhow::Result; #[derive(Debug)] pub struct Store { - path: String, + path: PathBuf, } impl Store { - pub fn open(path: impl ToString) -> Result { - let path = path.to_string(); + pub fn open(path: PathBuf) -> Result { fs::create_dir_all(&path)?; Ok(Self { path }) } @@ -44,8 +44,7 @@ impl Store { } pub fn get(&self, topic: &str) -> Result> { - let base = &self.path; - let path = format!("{base}/{topic}"); + let path = self.path.join(topic); let content = fs::read_to_string(path)?; Ok(content.split(SEPARATOR).map(String::from).collect()) } @@ -53,8 +52,7 @@ impl Store { pub fn insert(&mut self, topic: &str, content: String) -> Result<()> { let content = content.replace('\u{c}', " "); let content = content.trim(); - let base = &self.path; - let path = format!("{base}/{topic}"); + let path = self.path.join(topic); match OpenOptions::new().append(true).create(false).open(&path) { Ok(mut file) => write!(&mut file, "{SEPARATOR}\n{content}\n")?, Err(error) if error.kind() == ErrorKind::NotFound => drop(fs::write(path, content)),