use serde::Deserialize;
use super::value::Value;
#[derive(Debug, Clone, Deserialize)]
pub struct IREffectDeclaration {
pub name: String,
#[serde(default)]
pub operations: Vec<IREffectOperation>,
#[serde(default)]
pub source_line: u32,
#[serde(default)]
pub source_column: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IREffectOperation {
pub name: String,
#[serde(default)]
pub type_parameters: Vec<String>,
#[serde(default)]
pub parameter_names: Vec<String>,
#[serde(default)]
pub parameter_types: Vec<String>,
#[serde(default)]
pub return_type: String,
#[serde(default)]
pub source_line: u32,
#[serde(default)]
pub source_column: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IRPerform {
pub effect_name: String,
pub operation_name: String,
#[serde(default)]
pub arguments: Vec<String>,
#[serde(default)]
pub state_id: u32,
#[serde(default)]
pub resume_label: String,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IRHandlerClause {
pub operation_name: String,
#[serde(default)]
pub parameter_names: Vec<String>,
#[serde(default)]
pub body: Vec<Instruction>,
#[serde(default)]
pub source_line: u32,
#[serde(default)]
pub source_column: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IRHandlerFrame {
pub effect_names: Vec<String>,
#[serde(default)]
pub clauses: Vec<IRHandlerClause>,
#[serde(default)]
pub body: Vec<Instruction>,
#[serde(default)]
pub frame_id: u32,
#[serde(default)]
pub body_states: Vec<u32>,
#[serde(default)]
pub source_line: u32,
#[serde(default)]
pub source_column: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IRResume {
#[serde(default)]
pub value_expr: String,
#[serde(default)]
pub frame_id: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IRAbort {
#[serde(default)]
pub value_expr: String,
#[serde(default)]
pub frame_id: u32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct IRForward {
pub effect_name: String,
pub operation_name: String,
#[serde(default)]
pub arguments: Vec<String>,
#[serde(default)]
pub source_frame_id: u32,
#[serde(default)]
pub state_id: u32,
#[serde(default)]
pub resume_label: String,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "node_type", rename_all = "snake_case")]
pub enum Instruction {
Perform(IRPerform),
HandlerFrame(IRHandlerFrame),
Resume(IRResume),
Abort(IRAbort),
Forward(IRForward),
#[serde(other)]
Passthrough,
}
#[derive(Debug)]
pub enum EffectIRError {
DeserializeFailed(serde_json::Error),
InvalidShape(String),
}
impl std::fmt::Display for EffectIRError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EffectIRError::DeserializeFailed(e) => write!(f, "deserialize failed: {e}"),
EffectIRError::InvalidShape(s) => write!(f, "invalid IR shape: {s}"),
}
}
}
impl std::error::Error for EffectIRError {}
impl From<serde_json::Error> for EffectIRError {
fn from(e: serde_json::Error) -> Self {
EffectIRError::DeserializeFailed(e)
}
}
pub fn parse_block(json: &str) -> Result<Vec<Instruction>, EffectIRError> {
Ok(serde_json::from_str(json)?)
}
pub fn parse_effect(json: &str) -> Result<IREffectDeclaration, EffectIRError> {
Ok(serde_json::from_str(json)?)
}
pub fn resolve_arguments(args: &[String]) -> Vec<Value> {
args.iter().map(|s| Value::from_argument_text(s)).collect()
}