Files
zesdex/crates/zesdex-cms/src/infrastructure/persistence/conversation_repo.rs
T
asepharyana 5aaedbf787 docs: tambah doc comment, logging, dan inline comments di semua 255 file
Meliputi:
- File-level //! doc comment: tujuan file, alur kerja, komponen utama
- Function-level /// doc comment: apa, parameter, return, flow, edge cases
- Struct/enum/trait /// doc comment: peran, field docs
- Tracing logging (tracing::info!/debug!/trace!/warn!/error!) di setiap fungsi
- Inline comments untuk variable dan branching logic penting
- Seluruh 8 crates di workspace: zesdex-backend, zesdex-cms, zesdex-entities,
  zesdex-iam, zesdex-infra, zesdex-ipc, zesdex-middleware, zesdex-utils
- Build: 0 errors, 242/242 tests passed
2026-07-19 17:05:47 +07:00

58 lines
2.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! JSON filebacked `ConversationRepository` implementation.
//!
//! Stores `Conversation` as pretty-printed JSON at `<session_dir>/conversation.json`.
//! Uses atomic write (temp file + rename + fsync) for crash safety.
//!
//! ## Data Flow
//! - `load()`: read file → deserialize JSON → return Conversation
//! - `save()`: serialize Conversation → atomic write to conversation.json
use std::path::Path;
use anyhow::{Context, Result};
use zesdex_utils::write_json_atomic;
use crate::domain::conversation::Conversation;
use crate::domain::repository::ConversationRepository;
/// File-based `ConversationRepository` that reads/writes `conversation.json`.
///
/// Zero-allocation: the struct is a unit type marker.
#[derive(Debug, Clone, Default)]
pub struct JsonConversationRepository;
impl JsonConversationRepository {
/// Create a new repository instance.
pub fn new() -> Self {
Self
}
}
impl ConversationRepository for JsonConversationRepository {
/// Load a `Conversation` from `<session_dir>/conversation.json`.
///
/// Flow: read file → parse JSON → return Conversation.
fn load(&self, session_dir: &Path) -> Result<Conversation> {
let path = session_dir.join("conversation.json");
let data = std::fs::read_to_string(&path)
.with_context(|| format!("failed to read conversation at '{}'", path.display()))?;
let conv: Conversation = serde_json::from_str(&data)
.with_context(|| format!("failed to parse conversation at '{}'", path.display()))?;
Ok(conv)
}
/// Persist a `Conversation` to `<session_dir>/conversation.json`.
///
/// Flow: create session dir → atomic JSON write → log success.
fn save(&self, session_dir: &Path, conversation: &Conversation) -> Result<()> {
tracing::debug!("saving conversation to {session_dir:?}");
std::fs::create_dir_all(session_dir)
.with_context(|| format!("failed to create session dir '{}'", session_dir.display()))?;
let path = session_dir.join("conversation.json");
write_json_atomic(&path, conversation, None)
.with_context(|| "failed to save conversation")?;
tracing::debug!("conversation saved to '{}'", path.display());
Ok(())
}
}