use std::collections::HashMap;
use crate::decoder::{RawBlock, RawCostume, RawSound};
pub enum RawTarget {
Sprite(RawSprite),
Stage(RawStage),
}
impl<'de> serde::Deserialize<'de> for RawTarget {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let v = serde_json::Value::deserialize(deserializer)?;
let is_stage = v
.get("isStage")
.and_then(|val| val.as_bool())
.ok_or_else(|| serde::de::Error::missing_field("isStage"))?;
if is_stage {
let stage: RawStage = serde_json::from_value(v).map_err(serde::de::Error::custom)?;
Ok(RawTarget::Stage(stage))
} else {
let sprite: RawSprite = serde_json::from_value(v).map_err(serde::de::Error::custom)?;
Ok(RawTarget::Sprite(sprite))
}
}
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RawSprite {
pub name: String,
pub variables: HashMap<String, RawVariable>,
pub lists: HashMap<String, (String, Vec<serde_json::Value>)>,
pub blocks: HashMap<String, RawBlock>,
pub current_costume: usize,
pub costumes: Vec<RawCostume>,
pub sounds: Vec<RawSound>,
pub volume: u8,
pub layer_order: isize,
pub visible: bool,
pub x: i32,
pub y: i32,
pub size: u32,
pub direction: i32,
pub draggable: bool,
pub rotation_style: String,
}
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RawStage {
pub variables: HashMap<String, RawVariable>,
pub lists: HashMap<String, (String, Vec<serde_json::Value>)>,
pub broadcasts: HashMap<String, String>,
pub blocks: HashMap<String, RawBlock>,
#[serde(rename = "currentCostume")]
pub current_backdrop: usize,
#[serde(rename = "costumes")]
pub backdrops: Vec<RawCostume>,
pub sounds: Vec<RawSound>,
pub volume: u8,
}
#[derive(serde::Deserialize)]
pub struct RawVariable {
pub name: String,
pub value: serde_json::Value,
}