use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct YieldRequest {
pub interrupt_id: String,
pub message: String,
pub schema: Option<serde_json::Value>,
pub resume_mode: ResumeMode,
pub payload_ref: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
#[non_exhaustive]
pub enum ResumeMode {
#[default]
ReEntry,
Handoff,
}
impl YieldRequest {
pub fn simple(message: impl Into<String>) -> Self {
let msg = message.into();
Self {
interrupt_id: msg.clone(),
message: msg,
schema: None,
resume_mode: ResumeMode::default(),
payload_ref: None,
}
}
pub fn new(interrupt_id: impl Into<String>, message: impl Into<String>) -> Self {
Self {
interrupt_id: interrupt_id.into(),
message: message.into(),
schema: None,
resume_mode: ResumeMode::default(),
payload_ref: None,
}
}
pub fn with_schema(mut self, schema: serde_json::Value) -> Self {
self.schema = Some(schema);
self
}
pub fn with_resume_mode(mut self, mode: ResumeMode) -> Self {
self.resume_mode = mode;
self
}
pub fn with_payload_ref(mut self, reference: impl Into<String>) -> Self {
self.payload_ref = Some(reference.into());
self
}
}
impl fmt::Display for YieldRequest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}] {}", self.interrupt_id, self.message)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
#[non_exhaustive]
pub struct ResumeContext {
pub actor: Option<String>,
pub metadata: Option<serde_json::Value>,
}
impl ResumeContext {
pub fn new(actor: impl Into<String>) -> Self {
Self {
actor: Some(actor.into()),
metadata: None,
}
}
pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self {
self.metadata = Some(metadata);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResumeRecord {
pub interrupt_id: String,
pub thread_id: String,
pub node_name: String,
pub actor: Option<String>,
pub resumed_at: chrono::DateTime<chrono::Utc>,
pub response_hash: String,
}
pub fn compute_response_hash(input: &serde_json::Value) -> String {
use sha2::{Digest, Sha256};
let canonical = serde_json::to_string(input).unwrap_or_default();
let mut hasher = Sha256::new();
hasher.update(canonical.as_bytes());
let result = hasher.finalize();
hex::encode(result)
}