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