use crate::coroutine::Fault;
use crate::coroutine::{Coroutine, Value};
use crate::instr::Endpoint;
fn val_type_of(value: &Value) -> telltale_types::ValType {
use telltale_types::ValType;
match value {
Value::Unit => ValType::Unit,
Value::Nat(_) => ValType::Nat,
Value::Bool(_) => ValType::Bool,
Value::Str(_) => ValType::String,
Value::Prod(left, right) => {
ValType::Prod(Box::new(val_type_of(left)), Box::new(val_type_of(right)))
}
Value::Endpoint(ep) => ValType::Chan {
sid: ep.sid,
role: ep.role.clone(),
},
}
}
pub fn endpoint_from_reg(coro: &Coroutine, reg: u16) -> Result<Endpoint, Fault> {
match coro.regs.get(usize::from(reg)).cloned() {
Some(Value::Endpoint(ep)) => Ok(ep),
Some(other) => Err(Fault::TypeViolation {
expected: telltale_types::ValType::Chan {
sid: 0,
role: String::new(),
},
actual: val_type_of(&other),
message: "expected endpoint register".to_string(),
}),
None => Err(Fault::OutOfRegisters),
}
}
#[must_use]
pub fn decode_endpoint_fact(value: Value) -> Option<(Endpoint, String)> {
match value {
Value::Prod(left, right) => match (*left, *right) {
(Value::Endpoint(endpoint), Value::Str(fact)) => Some((endpoint, fact)),
_ => None,
},
_ => None,
}
}
pub fn decode_branch_label_payload(role: &str, payload: &Value) -> Result<String, Fault> {
match payload {
Value::Str(label) => Ok(label.clone()),
other => Err(Fault::TypeViolation {
expected: telltale_types::ValType::String,
actual: val_type_of(other),
message: format!("{role}: choose expects string branch label payload"),
}),
}
}