use serde::Deserialize; #[derive(Debug, Clone, Deserialize)] pub struct Level { id: String, sort_order: i32, name: String, description: String, #[serde(default)] is_sandbox: bool, init_board: Option, inputs: IOData, outputs: IOData, } #[derive(Debug, Clone, Deserialize)] #[serde(untagged)] pub enum IOData { Bytes(Vec), Text(String), } impl IOData { pub fn as_bytes(&self) -> &[u8] { match self { IOData::Bytes(b) => b, IOData::Text(t) => t.as_bytes(), } } } impl Level { pub fn id(&self) -> &str { &self.id } pub fn sort_order(&self) -> i32 { self.sort_order } pub fn name(&self) -> &str { &self.name } pub fn description(&self) -> &str { &self.description } pub fn is_sandbox(&self) -> bool { self.is_sandbox } pub fn init_board(&self) -> Option { self.init_board.clone() } pub fn inputs(&self) -> &[u8] { self.inputs.as_bytes() } pub fn outputs(&self) -> &[u8] { self.outputs.as_bytes() } pub fn input_is_text(&self) -> bool { matches!(self.inputs, IOData::Text(_)) } pub fn output_is_text(&self) -> bool { matches!(self.outputs, IOData::Text(_)) } }