use std::path::{Path, PathBuf};
use crate::infra::driven::cozo::adapter::CozoAdapter;
use crate::infra::driven::cozo::store::CozoFileStore;
use crate::infra::driven::fs::config::{CartularyConfig, KindConfig};
use crate::infra::driven::fs::decision_record_repository::FsDecisionRecordRepository;
use crate::infra::driven::fs::id_generator::{UlidDecisionRecordIdGenerator, UlidIssueIdGenerator};
use crate::infra::driven::fs::issue_repository::FsIssueRepository;
use crate::infra::driving::cli::OutputFormat;
use crate::domain::model::status::StatusesConfig;
pub(crate) struct Context<'cfg> {
pub output_fmt: OutputFormat,
pub root_dir: PathBuf,
pub issues_statuses: &'cfg StatusesConfig,
issues_dir: PathBuf,
issues_id_prefix: Option<String>,
config: &'cfg CartularyConfig,
}
impl<'cfg> Context<'cfg> {
pub fn new(config: &'cfg CartularyConfig, root_dir: PathBuf, output_fmt: OutputFormat) -> Self {
Self {
output_fmt,
root_dir,
issues_statuses: &config.issues_statuses,
issues_dir: config.issues_dir.clone(),
issues_id_prefix: config.issues_id_prefix.clone(),
config,
}
}
pub fn issue_repository(&self) -> FsIssueRepository {
FsIssueRepository {
dir: self.issues_dir.clone(),
union: self.config.issues_union.clone(),
id_prefix: self.issues_id_prefix.clone(),
statuses: self.issues_statuses.clone(),
schema_version: self.config.schema_version,
}
}
pub fn issue_id_generator(&self) -> UlidIssueIdGenerator {
UlidIssueIdGenerator {
id_prefix: self
.issues_id_prefix
.clone()
.unwrap_or_else(|| "ISSUE".to_string()),
}
}
pub fn decision_record_id_generator(
&self,
kind_cfg: &KindConfig,
) -> UlidDecisionRecordIdGenerator {
UlidDecisionRecordIdGenerator {
id_prefix: kind_cfg
.id_prefix
.clone()
.unwrap_or_else(|| kind_cfg.kind.to_uppercase()),
}
}
pub fn decision_record_repository(&self, kind_cfg: &KindConfig) -> FsDecisionRecordRepository {
FsDecisionRecordRepository {
dir: kind_cfg.dir.clone(),
union: kind_cfg.union.clone(),
kind: kind_cfg.kind.clone(),
id_prefix: kind_cfg.id_prefix.clone(),
schema_version: self.config.schema_version,
}
}
pub fn issue_defect_scanner(
&self,
) -> crate::infra::driven::fs::issue_defect_scanner::FsIssueDefectScanner {
crate::infra::driven::fs::issue_defect_scanner::FsIssueDefectScanner {
dir: self.issues_dir.clone(),
union: self.config.issues_union.clone(),
id_prefix: self.issues_id_prefix.clone(),
statuses: self.issues_statuses.clone(),
schema_version: self.config.schema_version,
}
}
pub fn decision_record_defect_scanner(
&self,
kind_cfg: &KindConfig,
) -> crate::infra::driven::fs::decision_record_defect_scanner::FsDecisionRecordDefectScanner
{
crate::infra::driven::fs::decision_record_defect_scanner::FsDecisionRecordDefectScanner {
dir: kind_cfg.dir.clone(),
union: kind_cfg.union.clone(),
kind: kind_cfg.kind.clone(),
id_prefix: kind_cfg.id_prefix.clone(),
schema_version: self.config.schema_version,
}
}
pub fn issues_dir(&self) -> &Path {
&self.issues_dir
}
pub fn issues_id_prefix(&self) -> Option<&str> {
self.issues_id_prefix.as_deref()
}
pub fn query_store(&self) -> CozoFileStore {
CozoFileStore::new(self.config.query_dir.clone())
}
pub fn query_runner(&self) -> anyhow::Result<CozoAdapter> {
let issue_repo = self.issue_repository();
let dr_owned: Vec<(String, FsDecisionRecordRepository)> = self
.config
.decision_kinds
.iter()
.map(|k| (k.kind.clone(), self.decision_record_repository(k)))
.collect();
use crate::domain::usecases::decision_record::DecisionRecordRepository;
let dr_refs: Vec<(String, &dyn DecisionRecordRepository)> = dr_owned
.iter()
.map(|(k, r)| (k.clone(), r as &dyn DecisionRecordRepository))
.collect();
CozoAdapter::from_workspace(
&issue_repo,
&dr_refs,
&self.config.tag_descriptors_for("issues"),
)
}
pub fn config(&self) -> &'cfg CartularyConfig {
self.config
}
pub fn load_known_refs(&self) -> anyhow::Result<crate::domain::model::entity_ref::KnownRefs> {
let dr_repos: Vec<
crate::infra::driven::fs::decision_record_repository::FsDecisionRecordRepository,
> = self
.config
.decision_kinds
.iter()
.map(|k| self.decision_record_repository(k))
.collect();
let dr_refs: Vec<&dyn crate::domain::usecases::decision_record::DecisionRecordRepository> =
dr_repos
.iter()
.map(|r| {
r as &dyn crate::domain::usecases::decision_record::DecisionRecordRepository
})
.collect();
let issue_repo = self.issue_repository();
crate::domain::usecases::links::load_known_refs(&dr_refs, &issue_repo)
}
}