use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
pub enum StepResult {
Continue(String),
Final(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Cell {
pub script: String,
pub output: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct Notebook {
pub cells: Vec<Cell>,
}
impl Notebook {
pub fn push(&mut self, script: String, output: String) {
self.cells.push(Cell { script, output });
}
pub fn as_history(&self) -> String {
self.cells
.iter()
.enumerate()
.map(|(i, c)| {
format!(
"# Cell {}\n```\n{}\n```\nOutput:\n{}",
i, c.script, c.output
)
})
.collect::<Vec<_>>()
.join("\n\n")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn notebook_push_and_history() {
let mut nb = Notebook::default();
assert!(nb.as_history().is_empty());
nb.push("ctx_len()".into(), "42".into());
let h = nb.as_history();
assert!(h.contains("Cell 0"));
assert!(h.contains("ctx_len()"));
assert!(h.contains("42"));
}
#[test]
fn step_result_variants() {
let c = StepResult::Continue("out".into());
let f = StepResult::Final("answer".into());
assert!(matches!(c, StepResult::Continue(_)));
assert!(matches!(f, StepResult::Final(_)));
}
}