diff --git a/src/nex.rs b/src/nex.rs index 202f918..810f865 100644 --- a/src/nex.rs +++ b/src/nex.rs @@ -51,10 +51,7 @@ impl Nex { for u in &config.user { let mut p = PathBuf::from(&target); p.push(u); - fs::create_dir_all(&p)?; - if let Some(ref permissions) = dir_permissions { - fs::set_permissions(&p, permissions.clone())? - } + persist_dir(&p, &dir_permissions)?; users.insert(u.clone(), p); } // init document template formatter @@ -98,25 +95,23 @@ impl Nex { } p.push(published.format("%Y").to_string()); + self.persist_dir(&p)?; if let Some(ref mut i) = index { i.push(p.clone()) } p.push(published.format("%m").to_string()); + self.persist_dir(&p)?; if let Some(ref mut i) = index { i.push(p.clone()) } p.push(published.format("%d").to_string()); + self.persist_dir(&p)?; if let Some(ref mut i) = index { i.push(p.clone()) } - fs::create_dir_all(&p)?; - if let Some(ref permissions) = self.dir_permissions { - fs::set_permissions(&p, permissions.clone())? - } - // init shared post ID once let id = published .format(self.filename.trim_matches('/')) @@ -131,10 +126,7 @@ impl Nex { // as usually hidden but accessible (in servers like Nexy) let mut d = PathBuf::from(&p); d.push(format!(".{id}")); - fs::create_dir_all(&d)?; - if let Some(ref permissions) = self.dir_permissions { - fs::set_permissions(&p, permissions.clone())? - } + self.persist_dir(&d)?; // create system meta file to track post time updated // if this meta file exists and has timestamp changed, also cleanup attachment files to update @@ -144,11 +136,8 @@ impl Nex { let state = timestamp.to_string(); if !fs::read_to_string(&s).is_ok_and(|this| this == state) { fs::remove_dir_all(&d)?; - fs::create_dir_all(&d)?; - if let Some(ref permissions) = self.dir_permissions { - fs::set_permissions(&p, permissions.clone())? - } - self.persist(&s, ×tamp, state.as_bytes())?; + self.persist_dir(&d)?; + self.persist_file(&s, ×tamp, state.as_bytes())?; } else { if let Some(ref mut i) = index { if let Some(ref a) = attachments { @@ -168,7 +157,7 @@ impl Nex { } // save post file, set its change status - let change = self.persist( + let change = self.persist_file( &f, ×tamp, self.template @@ -285,8 +274,13 @@ impl Nex { self.is_cleanup } - /// Wrapper function to change time updated for new file, according to the Snac time. - fn persist(&self, path: &PathBuf, modified: &DateTime, data: &[u8]) -> Result { + /// Create new file for `Self`; change time updated, according to the Snac time. + fn persist_file( + &self, + path: &PathBuf, + modified: &DateTime, + data: &[u8], + ) -> Result { use std::io::Write; let status = if fs::exists(path)? { Change::Updated @@ -303,8 +297,14 @@ impl Nex { } Ok(status) } + + /// Create directory for `Self`, ignore destination exists error case + fn persist_dir(&self, path: &PathBuf) -> Result<()> { + persist_dir(path, &self.dir_permissions) + } } +/// Set permissions for given platform fn permissions(config: Option, default: u32) -> Option { { #[cfg(any(target_os = "linux", target_os = "macos"))] @@ -318,3 +318,16 @@ fn permissions(config: Option, default: u32) -> Option { } } } + +/// Create directory with given permissions, ignore errors on destination exists +fn persist_dir(path: &PathBuf, permissions: &Option) -> Result<()> { + if let Err(e) = fs::create_dir(path) { + if !matches!(e.kind(), std::io::ErrorKind::AlreadyExists) { + bail!(e) + } + } + if let Some(p) = permissions { + fs::set_permissions(path, p.clone())? + } + Ok(()) +}