use std::collections::HashMap;
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RawBlock {
pub opcode: String,
pub next: Option<String>,
pub parent: Option<String>,
pub inputs: HashMap<String, RawBlockInput>,
pub fields: HashMap<String, (String, Option<String>)>,
pub top_level: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RawBlockInput {
pub shadow: u8,
pub kind: u8,
pub value: serde_json::Value,
}
impl<'de> serde::Deserialize<'de> for RawBlockInput {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let vec: Vec<serde_json::Value> = serde::Deserialize::deserialize(deserializer)?;
if vec.len() < 2 {
return Err(serde::de::Error::custom("Invalid RawBlockInput format"));
}
let shadow = vec[0]
.as_u64()
.ok_or_else(|| serde::de::Error::custom("Invalid shadow value"))? as u8;
if let Some(block_id) = vec[1].as_str() {
return Ok(RawBlockInput {
shadow,
kind: 0, value: serde_json::Value::String(block_id.to_string()),
});
}
if let Some(sub_vec) = vec[1].as_array() {
if sub_vec.len() < 2 {
return Err(serde::de::Error::custom("Invalid sub-array format"));
}
let kind = sub_vec[0]
.as_u64()
.ok_or_else(|| serde::de::Error::custom("Invalid type value"))? as u8;
let value = sub_vec[1].clone();
return Ok(RawBlockInput { shadow, kind, value });
}
Err(serde::de::Error::custom("Invalid RawBlockInput second element"))
}
}