use chrono::{DateTime, Utc};
#[derive(Clone, Debug, PartialEq)]
pub struct LeafMeta {
pub chunk_id: String,
pub session_id: String,
pub token_count: u32,
pub timestamp: DateTime<Utc>,
}
pub trait TreeLeafSink {
fn append_leaf(&self, markdown: &str, meta: &LeafMeta) -> anyhow::Result<Vec<String>>;
}
#[derive(Clone, Debug, PartialEq)]
pub struct RecordedLeaf {
pub markdown: String,
pub meta: LeafMeta,
}
#[derive(Default)]
pub struct RecordingSink {
leaves: std::sync::Mutex<Vec<RecordedLeaf>>,
seal_ids: Vec<String>,
}
impl RecordingSink {
pub fn new() -> Self {
Self::default()
}
pub fn with_seal_ids(seal_ids: Vec<String>) -> Self {
Self {
leaves: std::sync::Mutex::new(Vec::new()),
seal_ids,
}
}
pub fn leaves(&self) -> Vec<RecordedLeaf> {
self.leaves.lock().expect("recording sink poisoned").clone()
}
pub fn len(&self) -> usize {
self.leaves.lock().expect("recording sink poisoned").len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl TreeLeafSink for RecordingSink {
fn append_leaf(&self, markdown: &str, meta: &LeafMeta) -> anyhow::Result<Vec<String>> {
self.leaves
.lock()
.expect("recording sink poisoned")
.push(RecordedLeaf {
markdown: markdown.to_string(),
meta: meta.clone(),
});
Ok(self.seal_ids.clone())
}
}
pub(crate) fn now() -> DateTime<Utc> {
Utc::now()
}