From 71f8f71b368672ef9060b1c4ec9834e08e89522b Mon Sep 17 00:00:00 2001 From: Nathan McCarty Date: Thu, 16 Mar 2023 15:42:05 -0400 Subject: [PATCH] feat: Page::write method --- src/site.rs | 8 ++++++++ src/site/page.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/site.rs b/src/site.rs index da279e1..a25c702 100644 --- a/src/site.rs +++ b/src/site.rs @@ -17,6 +17,7 @@ pub mod page; /// Error encountered interacting with a [`Site`] #[derive(Snafu, Debug)] +#[snafu(visibility(pub(crate)))] pub enum SiteError { /// Error checking to see if a path exists #[snafu(display("Error checking if path exists: {:?}", path))] @@ -53,6 +54,13 @@ pub enum SiteError { /// The underlying error source: std::io::Error, }, + /// Failed to write out a page stub + WritePageStub { + /// The path we tried to write the page stub to + path: PathBuf, + /// The underlying error + source: std::io::Error, + }, /// Error writing out a page #[snafu(display("Error writing out page {:?}", page))] PageWrite { diff --git a/src/site/page.rs b/src/site/page.rs index 3ad061c..f1d0dee 100644 --- a/src/site/page.rs +++ b/src/site/page.rs @@ -1,10 +1,19 @@ //! Management of a page -use std::path::{Path, PathBuf}; +use std::{ + fs::{create_dir_all, File}, + io::Write, + path::{Path, PathBuf}, +}; use serde::{Deserialize, Serialize}; +use snafu::{ensure, ResultExt}; +use tracing::{debug, instrument}; -use super::SiteError; +use super::{ + ConfigReifySnafu, CreateDirectorySnafu, ExistanceCheckSnafu, NotADirectorySnafu, SiteError, + WriteConfigSnafu, WritePageStubSnafu, +}; /// Representation of the configuration for a page #[derive(Serialize, Deserialize, Debug)] @@ -57,11 +66,47 @@ impl Page { /// /// Will return an error if serialization fails, the user does not have write permissions for /// the directory, or any other IO errors occur while writing out the config. + #[instrument(skip(site_path, page_dir))] pub fn write( &self, site_path: impl AsRef, - page_path: impl AsRef, + page_dir: impl AsRef, ) -> Result<(), SiteError> { - todo!() + // build the page_dir + let page_dir = site_path.as_ref().join("pages").join(page_dir.as_ref()); + debug!(?page_dir); + // Make sure the page path is a dir if it exists, otherwise create it + if page_dir + .try_exists() + .context(ExistanceCheckSnafu { path: &page_dir })? + { + ensure!(page_dir.is_dir(), NotADirectorySnafu { path: &page_dir }); + } else { + create_dir_all(&page_dir).context(CreateDirectorySnafu { path: &page_dir })?; + } + // Serialize the config + let config_path = page_dir.join("page.dhall"); + let serialized_config = serde_dhall::serialize(&self.config) + .to_string() + .context(ConfigReifySnafu)?; + let mut config_file = + File::create(&config_path).context(WriteConfigSnafu { path: &config_path })?; + config_file + .write_all(serialized_config.as_bytes()) + .context(WriteConfigSnafu { path: &config_path })?; + // Create the page file if it doesn't exist + let page_path = page_dir.join(&self.file); + if !page_path + .try_exists() + .context(ExistanceCheckSnafu { path: &page_dir })? + { + let contents = format!("# {}\n\n", self.config.title); + let mut page_file = + File::create(&page_path).context(WritePageStubSnafu { path: &page_path })?; + page_file + .write_all(contents.as_bytes()) + .context(WritePageStubSnafu { path: &page_path })?; + } + Ok(()) } }