use super::opcode;
pub type ScriptId = u32;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ScriptStatus {
raw: u32,
}
impl ScriptStatus {
pub fn from_raw(raw: u32) -> Self {
Self { raw }
}
pub fn raw(&self) -> u32 {
self.raw
}
pub fn running(&self) -> bool {
self.raw & opcode::SCRIPT_STATUS_RUN != 0
}
pub fn msg_pending(&self) -> bool {
self.raw & opcode::SCRIPT_STATUS_MSG != 0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorCategory {
Compile,
Runtime,
Other(u32),
}
impl ErrorCategory {
pub fn from_raw(v: u32) -> Self {
match v {
opcode::ERRTYPE_COMPILE => Self::Compile,
opcode::ERRTYPE_RUN => Self::Runtime,
_ => Self::Other(v),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum ScriptValue {
Nil,
Boolean(bool),
Integer(i32),
String(String),
Table(String),
Unsupported,
}
impl ScriptValue {
pub fn decode(subtype: u32, data: &[u8]) -> Self {
match subtype {
opcode::TYPE_NIL => ScriptValue::Nil,
opcode::TYPE_BOOLEAN => {
let b = data.first().copied().unwrap_or(0) != 0;
ScriptValue::Boolean(b)
}
opcode::TYPE_INTEGER => {
if data.len() >= 4 {
ScriptValue::Integer(i32::from_le_bytes([data[0], data[1], data[2], data[3]]))
} else {
ScriptValue::Unsupported
}
}
opcode::TYPE_STRING => ScriptValue::String(String::from_utf8_lossy(data).into_owned()),
opcode::TYPE_TABLE => ScriptValue::Table(String::from_utf8_lossy(data).into_owned()),
_ => ScriptValue::Unsupported,
}
}
}
#[derive(Debug, Clone)]
pub enum ScriptMsg {
None,
Error {
script_id: ScriptId,
category: ErrorCategory,
text: String,
},
Return {
script_id: ScriptId,
value: ScriptValue,
},
User {
script_id: ScriptId,
value: ScriptValue,
},
}