//! Memory use-case implementations for the CMS. //! //! `MemoryServiceImpl` implements `MemoryService` (defined in //! `domain::service`) and is generic over `R: MemoryRepository` //! (defined in `domain::repository`), delegating all persistence to that //! adapter. The repository is injected at composition root. //! //! ## Flow //! Each method delegates to the injected `repo` with the configured //! `memory_dir`. Error context is added at this layer to identify which //! memory operation failed. use std::path::PathBuf; use anyhow::{Context, Result}; use tracing; use crate::domain::memory::Memory; use crate::domain::repository::MemoryRepository; use crate::domain::service::MemoryService; /// Service implementation for memory CRUD operations. /// /// Generic over `R: MemoryRepository` so the persistence layer can be /// swapped without changing business logic. /// /// ## Fields /// - `repo` — injected memory repository implementation /// - `memory_dir` — base path where memory files are stored pub struct MemoryServiceImpl { pub repo: R, /// Base directory for memory storage files. pub memory_dir: PathBuf, } impl MemoryServiceImpl { /// Create a new service with the given repository and memory directory. /// /// ## Parameters /// - `repo` — the repository adapter to delegate persistence to /// - `memory_dir` — base path for memory files (converted via `Into`) pub fn new(repo: R, memory_dir: impl Into) -> Self { tracing::debug!("creating MemoryServiceImpl"); Self { repo, memory_dir: memory_dir.into(), } } } impl MemoryService for MemoryServiceImpl { /// List all stored memory names. /// /// Flow: delegate to repo.list() → wrap error with context. fn list_memories(&self) -> Result> { tracing::debug!("listing memories from {:?}", self.memory_dir); self.repo .list(&self.memory_dir) .context("failed to list memories") } /// Persist a memory to disk. /// /// Flow: delegate to repo.save() → wrap error with memory name context. fn save_memory(&self, memory: &Memory) -> Result<()> { tracing::debug!("saving memory '{}'", memory.name); self.repo .save(&self.memory_dir, memory) .with_context(|| format!("failed to save memory '{}'", memory.name)) } /// Delete a memory by name. /// /// Flow: delegate to repo.delete() → wrap error with memory name context. fn delete_memory(&self, name: &str) -> Result<()> { tracing::debug!("deleting memory '{name}'"); self.repo .delete(&self.memory_dir, name) .with_context(|| format!("failed to delete memory '{name}'")) } }