diff --git a/src/error.rs b/src/error.rs index dd49184..38be3c2 100644 --- a/src/error.rs +++ b/src/error.rs @@ -7,11 +7,11 @@ use tracing::error; #[derive(Error, Debug)] #[allow(clippy::enum_variant_names)] pub enum PostError { - #[error(transparent)] + #[error("io error: {0}")] IoError(#[from] std::io::Error), - #[error("{0}")] + #[error("failed to parse post metadata: {0}")] ParseError(String), - #[error("{0}")] + #[error("failed to render post: {0}")] RenderError(String), #[error("post {0:?} not found")] NotFound(String), diff --git a/src/main.rs b/src/main.rs index 9dcee40..7296652 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,6 @@ mod templates; use std::future::IntoFuture; use std::net::SocketAddr; -use std::path::PathBuf; use std::process::exit; use std::sync::Arc; use std::time::Duration; @@ -114,7 +113,7 @@ async fn main() -> eyre::Result<()> { } Engine::Blag => Arc::new(Blag::new( config.dirs.posts.clone().into(), - Some(PathBuf::from("blag").into()), + config.blag.bin.clone().into(), )), }; diff --git a/src/post/blag.rs b/src/post/blag.rs index b5632db..a704df3 100644 --- a/src/post/blag.rs +++ b/src/post/blag.rs @@ -1,8 +1,5 @@ -use std::future::Future; -use std::mem; -use std::path::{Path, PathBuf}; -use std::pin::Pin; -use std::process::{ExitStatus, Stdio}; +use std::path::Path; +use std::process::Stdio; use std::sync::Arc; use axum::async_trait; @@ -25,11 +22,8 @@ pub struct Blag { } impl Blag { - pub fn new(root: Arc, blag_bin: Option>) -> Blag { - Self { - root, - blag_bin: blag_bin.unwrap_or_else(|| PathBuf::from("blag").into()), - } + pub fn new(root: Arc, blag_bin: Arc) -> Blag { + Self { root, blag_bin } } } @@ -43,10 +37,24 @@ impl PostManager for Blag { let mut meow = Vec::new(); let mut files = tokio::fs::read_dir(&self.root).await?; - while let Ok(Some(entry)) = files.next_entry().await { + loop { + let entry = match files.next_entry().await { + Ok(Some(v)) => v, + Ok(None) => break, + Err(err) => { + error!("error while getting next entry: {err}"); + continue; + } + }; + let file_type = entry.file_type().await?; if file_type.is_file() { - let name = entry.file_name().into_string().unwrap(); + let name = match entry.file_name().into_string() { + Ok(v) => v, + Err(_) => { + continue; + } + }; if name.ends_with(".sh") { set.push(async move { self.get_post(name.trim_end_matches(".sh")).await }); @@ -115,7 +123,11 @@ impl PostManager for Blag { let mut cmd = tokio::process::Command::new(&*self.blag_bin) .arg(path) .stdout(Stdio::piped()) - .spawn()?; + .spawn() + .map_err(|err| { + error!("failed to spawn {:?}: {err}", self.blag_bin); + err + })?; let stdout = cmd.stdout.take().unwrap(); @@ -125,44 +137,17 @@ impl PostManager for Blag { let mut meta: PostMetadata = serde_json::from_str(&buf)?; meta.name = name.to_string(); - - enum Return { - Read(String), - Exit(ExitStatus), - } - - let mut futures: FuturesUnordered< - Pin> + Send>>, - > = FuturesUnordered::new(); - buf.clear(); - let mut fut_buf = mem::take(&mut buf); + reader.read_to_string(&mut buf).await?; - futures.push(Box::pin(async move { - reader - .read_to_string(&mut fut_buf) - .await - .map(|_| Return::Read(fut_buf)) - })); - futures.push(Box::pin(async move { cmd.wait().await.map(Return::Exit) })); + debug!("read output: {} bytes", buf.len()); - while let Some(res) = futures.next().await { - match res? { - Return::Read(fut_buf) => { - buf = fut_buf; - debug!("read output: {} bytes", buf.len()); - } - Return::Exit(exit_status) => { - debug!("exited: {exit_status}"); - if !exit_status.success() { - return Err(PostError::RenderError(exit_status.to_string())); - } - } - } + let exit_status = cmd.wait().await?; + debug!("exited: {exit_status}"); + if !exit_status.success() { + return Err(PostError::RenderError(exit_status.to_string())); } - drop(futures); - let elapsed = start.elapsed(); Ok(ReturnedPost::Rendered(