use eyre::{Result, eyre};
use crate::{Project, Vault};
pub struct ProjectBuilder<'a> {
project: Project,
vault: &'a mut Vault,
}
impl<'a> ProjectBuilder<'a> {
pub fn new(vault: &'a mut Vault, name: impl Into<String>) -> Self {
let id = vault.index.peek_next_canonical_project_id();
let project = Project::new(id, name);
Self {
project,
vault,
}
}
pub fn create(&mut self) -> Result<Project> {
self.project.id = self.vault.index.allocate_canonical_project_id();
self
.vault
.projects
.insert(self.project.id, self.project.clone());
self
.vault
.index
.project_key_to_canonical_id
.entry(self.project.key.clone())
.or_default()
.push(self.project.id);
self.vault.save()?;
Ok(self.project.clone())
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.project.description = Some(description.into());
self
}
pub fn with_key(mut self, key: impl Into<String>) -> Result<Self> {
let key = key.into();
if self
.vault
.index
.project_key_to_canonical_id
.contains_key(&key)
{
let existing: &Vec<u32> = self.vault.index.project_key_to_canonical_id[&key].as_ref();
for id in existing {
let proj = self.vault.projects[id].clone();
if !proj.is_complete() {
return Err(eyre!("Project with key {} already exists", &key));
}
}
}
self.project.key = key;
Ok(self)
}
}