use crate::storage::adapter::DataModelAdapter;
use crate::graph::tree::{DependencyMapping, FilesystemDependencyMapper};
use crate::core::error::SpecmanError;
use crate::storage::persistence::WorkspacePersistence;
use crate::templates::engine::{MarkdownTemplateEngine, TemplateEngine};
use crate::templates::catalog::TemplateCatalog;
use crate::workspace::{FilesystemWorkspaceLocator, WorkspaceLocator};
use std::path::Path;
use std::sync::Arc;
pub type DefaultWorkspaceLocator = Arc<FilesystemWorkspaceLocator>;
pub type DefaultPersistence = WorkspacePersistence<DefaultWorkspaceLocator>;
pub struct SpecmanEnv {
pub catalog: TemplateCatalog,
pub persistence: DefaultPersistence,
pub mapping: Arc<dyn DependencyMapping>,
pub templates: Arc<dyn TemplateEngine>,
}
impl SpecmanEnv {
pub fn from_current_dir() -> Result<Self, SpecmanError> {
let locator = Arc::new(FilesystemWorkspaceLocator::from_current_dir()?);
Self::new(locator, None)
}
pub fn from_path(path: impl AsRef<Path>) -> Result<Self, SpecmanError> {
let locator = Arc::new(FilesystemWorkspaceLocator::new(path.as_ref().to_path_buf()));
Self::new(locator, None)
}
pub fn new(
locator: DefaultWorkspaceLocator,
adapter: Option<Arc<dyn DataModelAdapter>>,
) -> Result<Self, SpecmanError> {
let workspace = locator.workspace()?;
let mapper = FilesystemDependencyMapper::new(locator.clone());
let inventory = mapper.inventory_handle();
let catalog = TemplateCatalog::new(workspace);
let persistence = if let Some(a) = adapter {
WorkspacePersistence::with_inventory_and_adapter(locator.clone(), inventory, a)
} else {
WorkspacePersistence::with_inventory(locator.clone(), inventory)
};
let templates = MarkdownTemplateEngine::new();
Ok(Self {
catalog,
persistence,
mapping: Arc::new(mapper),
templates: Arc::new(templates),
})
}
}