feat: Site write method

This commit is contained in:
Nathan McCarty 2023-03-16 15:18:03 -04:00
parent b598b7ad71
commit 2697989bcc
Signed by: thatonelutenist
GPG Key ID: D70DA3DD4D1E9F96
2 changed files with 116 additions and 2 deletions

View File

@ -1,12 +1,69 @@
//! Management of on-disk layout of the source of a site
use std::{collections::HashMap, path::PathBuf};
use std::{
collections::HashMap,
fs::{create_dir_all, File},
io::Write,
path::{Path, PathBuf},
};
use snafu::{ensure, ResultExt, Snafu};
use tracing::{debug, instrument};
use self::{config::Config, page::Page};
pub mod config;
pub mod page;
/// Error encountered interacting with a [`Site`]
#[derive(Snafu, Debug)]
pub enum SiteError {
/// Error checking to see if a path exists
#[snafu(display("Error checking if path exists: {:?}", path))]
ExistanceCheck {
/// Path being checked
path: PathBuf,
/// Underlying error
source: std::io::Error,
},
/// Error creating a directory
#[snafu(display("Error creating directory:: {:?}", path))]
CreateDirectory {
/// Path being checked
path: PathBuf,
/// Underlying error
source: std::io::Error,
},
/// Site repository dir was not a directory
#[snafu(display("Site repository path was not a directory: {:?}", path))]
NotADirectory {
/// Path being checked
path: PathBuf,
},
/// Failed to reify the configuration
ConfigReify {
/// The underlying error
#[snafu(source(from(serde_dhall::Error, Box::new)))]
source: Box<serde_dhall::Error>,
},
/// Failed to write out the configuration
WriteConfig {
/// The path we tried to write the config to
path: PathBuf,
/// The underlying error
source: std::io::Error,
},
/// Error writing out a page
#[snafu(display("Error writing out page {:?}", page))]
PageWrite {
/// The page we were trying to write out
page: PathBuf,
/// The underlying error
#[snafu(source(from(SiteError, Box::new)))]
source: Box<SiteError>,
},
}
/// Representation of the on-disk structure of a site
#[derive(Debug)]
pub struct Site {
@ -26,3 +83,42 @@ impl Default for Site {
}
}
}
impl Site {
/// Writes out the configuration for a `Site`, and makes sure the files for all the pages exist
///
/// # Errors
///
/// 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_dir))]
pub fn write(&self, site_dir: impl AsRef<Path>) -> Result<(), SiteError> {
let site_dir = site_dir.as_ref();
debug!(?site_dir);
// Make sure the site_dir is a directory, if it exists, otherwise create it
if site_dir
.try_exists()
.context(ExistanceCheckSnafu { path: site_dir })?
{
ensure!(site_dir.is_dir(), NotADirectorySnafu { path: site_dir });
} else {
create_dir_all(site_dir).context(CreateDirectorySnafu { path: site_dir })?;
}
// Serialize the config
let config_path = site_dir.join("config.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 })?;
// Write out the pages
for (page_path, page) in &self.pages {
page.write(site_dir, page_path)
.context(PageWriteSnafu { page: page_path })?;
}
Ok(())
}
}

View File

@ -1,9 +1,11 @@
//! Management of a page
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use super::SiteError;
/// Representation of the configuration for a page
#[derive(Serialize, Deserialize, Debug)]
pub struct PageConfig {
@ -47,3 +49,19 @@ impl Default for Page {
}
}
}
impl Page {
/// Writes out the configuration for a `Page`, and makes sure the file for the page exists
///
/// # Errors
///
/// 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.
pub fn write(
&self,
site_path: impl AsRef<Path>,
page_path: impl AsRef<Path>,
) -> Result<(), SiteError> {
todo!()
}
}