use serde_json::Value;
use crate::graph::state::State;
use crate::graph::trace::TraceEvent;
use super::types::Interrupt;
#[derive(Debug, Clone)]
pub struct InvokeResult<S: State> {
pub state: S,
pub interrupt: Option<Vec<Interrupt>>,
pub trace: Vec<TraceEvent>,
}
impl<S: State> InvokeResult<S> {
pub fn new(state: S) -> Self {
Self {
state,
interrupt: None,
trace: Vec::new(),
}
}
pub fn with_interrupt(state: S, interrupt: Vec<Interrupt>) -> Self {
Self {
state,
interrupt: Some(interrupt),
trace: Vec::new(),
}
}
pub fn new_with_trace(state: S, trace: Vec<TraceEvent>) -> Self {
Self {
state,
interrupt: None,
trace,
}
}
pub fn with_interrupt_and_trace(
state: S,
interrupt: Vec<Interrupt>,
trace: Vec<TraceEvent>,
) -> Self {
Self {
state,
interrupt: Some(interrupt),
trace,
}
}
pub fn to_json(&self) -> Result<Value, crate::graph::error::GraphError> {
let mut result = serde_json::to_value(&self.state)
.map_err(crate::graph::error::GraphError::SerializationError)?;
if let Some(ref interrupts) = self.interrupt {
result["__interrupt__"] = serde_json::to_value(interrupts)
.map_err(crate::graph::error::GraphError::SerializationError)?;
}
Ok(result)
}
pub fn has_interrupt(&self) -> bool {
self.interrupt.is_some()
}
pub fn interrupt(&self) -> Option<&Vec<Interrupt>> {
self.interrupt.as_ref()
}
}
impl<S: State> From<S> for InvokeResult<S> {
fn from(state: S) -> Self {
Self::new(state)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::graph::state::MessagesState;
#[test]
fn test_invoke_result() {
let state = MessagesState::new();
let result = InvokeResult::new(state);
assert!(!result.has_interrupt());
}
#[test]
fn test_invoke_result_with_interrupt() {
let state = MessagesState::new();
let interrupt = Interrupt::new(serde_json::json!("test"));
let result = InvokeResult::with_interrupt(state, vec![interrupt]);
assert!(result.has_interrupt());
}
}