Skip to main content

monoloop_connector_codex/
raw_dump.rs

1//! Optional raw NDJSON capture (test diagnostics only).
2
3use std::path::PathBuf;
4use std::sync::Mutex;
5
6/// Bounded collector for exact inbound/outbound NDJSON lines.
7#[derive(Debug, Default)]
8pub struct CodexRawDump {
9    lines: Mutex<Vec<String>>,
10    path: Option<PathBuf>,
11    max_lines: usize,
12}
13
14impl CodexRawDump {
15    /// Create an in-memory collector; optionally mirror to a file.
16    pub fn new(path: Option<PathBuf>, max_lines: usize) -> Self {
17        Self {
18            lines: Mutex::new(Vec::new()),
19            path,
20            max_lines: max_lines.max(1),
21        }
22    }
23
24    /// Record one complete NDJSON line.
25    pub fn push_line(&self, line: impl Into<String>) {
26        let line = line.into();
27        if let Ok(mut g) = self.lines.lock() {
28            if g.len() < self.max_lines {
29                g.push(line.clone());
30            }
31        }
32        if let Some(path) = &self.path {
33            use std::io::Write;
34            if let Ok(mut f) = std::fs::OpenOptions::new()
35                .create(true)
36                .append(true)
37                .open(path)
38            {
39                let _ = writeln!(f, "{line}");
40            }
41        }
42    }
43
44    /// Snapshot of captured lines.
45    pub fn snapshot(&self) -> Vec<String> {
46        self.lines.lock().map(|g| g.clone()).unwrap_or_default()
47    }
48
49    /// Join captured lines for file export.
50    pub fn as_text(&self) -> String {
51        self.snapshot().join("\n")
52    }
53}