Skip to main content

deepstrike_sdk/runtime/
archive.rs

1use deepstrike_core::types::message::Message;
2use std::error::Error;
3use std::fs::{self, File};
4use std::io::Write;
5use std::path::PathBuf;
6
7pub trait ArchiveStore: Send + Sync {
8    fn write(
9        &self,
10        session_id: &str,
11        seq: u64,
12        messages: &[Message],
13    ) -> Result<String, Box<dyn Error + Send + Sync>>;
14
15    fn read(&self, archive_ref: &str) -> Result<Vec<Message>, Box<dyn Error + Send + Sync>>;
16}
17
18pub struct NullArchiveStore;
19
20impl ArchiveStore for NullArchiveStore {
21    fn write(
22        &self,
23        _session_id: &str,
24        _seq: u64,
25        _messages: &[Message],
26    ) -> Result<String, Box<dyn Error + Send + Sync>> {
27        Ok(String::new())
28    }
29
30    fn read(&self, _archive_ref: &str) -> Result<Vec<Message>, Box<dyn Error + Send + Sync>> {
31        Err(Box::new(std::io::Error::new(
32            std::io::ErrorKind::NotFound,
33            "NullArchiveStore does not store archives",
34        )))
35    }
36}
37
38pub struct FileArchiveStore {
39    pub root: PathBuf,
40}
41
42impl FileArchiveStore {
43    pub fn new(root: PathBuf) -> Self {
44        Self { root }
45    }
46}
47
48impl ArchiveStore for FileArchiveStore {
49    fn write(
50        &self,
51        session_id: &str,
52        seq: u64,
53        messages: &[Message],
54    ) -> Result<String, Box<dyn Error + Send + Sync>> {
55        let dir = self.root.join(session_id);
56        fs::create_dir_all(&dir)?;
57        let file_path = dir.join(format!("{}.jsonl", seq));
58        let mut file = File::create(&file_path)?;
59
60        for msg in messages {
61            let line = serde_json::to_string(msg)?;
62            writeln!(file, "{}", line)?;
63        }
64
65        Ok(file_path.to_string_lossy().to_string())
66    }
67
68    fn read(&self, archive_ref: &str) -> Result<Vec<Message>, Box<dyn Error + Send + Sync>> {
69        let file = File::open(archive_ref)?;
70        let reader = std::io::BufReader::new(file);
71        let mut messages = Vec::new();
72        use std::io::BufRead;
73        for line in reader.lines() {
74            let line = line?;
75            if line.trim().is_empty() {
76                continue;
77            }
78            let msg: Message = serde_json::from_str(&line)?;
79            messages.push(msg);
80        }
81        Ok(messages)
82    }
83}