use crate::error::SigilStitchError;
use crate::spec::file_spec::FileSpec;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RenderedFile {
pub path: String,
pub content: String,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ProjectSpec {
pub(crate) files: Vec<FileSpec>,
}
impl ProjectSpec {
pub fn builder() -> ProjectSpecBuilder {
ProjectSpecBuilder { files: Vec::new() }
}
pub fn render(&self, width: usize) -> Result<Vec<RenderedFile>, SigilStitchError> {
let mut rendered = Vec::with_capacity(self.files.len());
for file in &self.files {
let content = file.render(width)?;
rendered.push(RenderedFile {
path: file.filename().to_string(),
content,
});
}
Ok(rendered)
}
pub fn write_to(
&self,
base_dir: &std::path::Path,
width: usize,
) -> Result<Vec<std::path::PathBuf>, SigilStitchError> {
let rendered = self.render(width)?;
let mut written = Vec::with_capacity(rendered.len());
for file in &rendered {
let full_path = base_dir.join(&file.path);
if let Some(parent) = full_path.parent() {
std::fs::create_dir_all(parent).map_err(|source| SigilStitchError::Io {
source,
context: format!("creating directory for {}", file.path),
})?;
}
std::fs::write(&full_path, &file.content).map_err(|source| SigilStitchError::Io {
source,
context: format!("writing file {}", file.path),
})?;
written.push(full_path);
}
Ok(written)
}
}
#[derive(Debug)]
pub struct ProjectSpecBuilder {
files: Vec<FileSpec>,
}
impl ProjectSpecBuilder {
pub fn add_file(mut self, file: FileSpec) -> Self {
self.files.push(file);
self
}
pub fn build(self) -> ProjectSpec {
ProjectSpec { files: self.files }
}
}