Started serializing the BlockFun structure

This commit is contained in:
Weird Constructor 2022-08-03 19:36:12 +02:00
parent 561781e3df
commit 9683213c28

View file

@ -177,6 +177,91 @@ impl Block {
} }
} }
} }
/// Serializes this [Block] into a [Value]. Called by [BlockArea::serialize].
pub fn serialize(&self) -> Value {
let mut inputs = json!([]);
let mut outputs = json!([]);
if let Value::Array(inputs) = &mut inputs {
for p in self.inputs.iter() {
inputs.push(json!(p));
}
}
if let Value::Array(outputs) = &mut outputs {
for p in self.outputs.iter() {
outputs.push(json!(p));
}
}
let c0 = if let Some(c) = self.contains.0 { c.into() } else { Value::Null };
let c1 = if let Some(c) = self.contains.1 { c.into() } else { Value::Null };
let mut contains = json!([c0, c1]);
json!({
"id": self.id as i64,
"rows": self.rows as i64,
"contains": contains,
"expanded": self.expanded,
"typ": self.typ,
"lbl": self.lbl,
"color": self.color,
"inputs": inputs,
"outputs": outputs,
})
}
/// Deserializes this [Block] from a [Value]. Called by [BlockArea::deserialize].
pub fn deserialize(v: &Value) -> Result<Box<Block>, serde_json::Error> {
let mut inputs = vec![];
let mut outputs = vec![];
let inps = &v["inputs"];
if let Value::Array(inps) = inps {
for v in inps.iter() {
inputs.push(if v.is_string() {
Some(v.as_str().unwrap_or("").to_string())
} else {
None
})
}
}
let outs = &v["outputs"];
if let Value::Array(outs) = outs {
for v in outs.iter() {
outputs.push(if v.is_string() {
Some(v.as_str().unwrap_or("").to_string())
} else {
None
})
}
}
Ok(Box::new(Block {
id: v["id"].as_i64().unwrap_or(0) as usize,
rows: v["rows"].as_i64().unwrap_or(0) as usize,
contains: (
if v["contains"][0].is_i64() {
Some(v["contains"][0].as_i64().unwrap_or(0) as usize)
} else {
None
},
if v["contains"][1].is_i64() {
Some(v["contains"][1].as_i64().unwrap_or(0) as usize)
} else {
None
},
),
expanded: v["expanded"].as_bool().unwrap_or(true),
typ: v["typ"].as_str().unwrap_or("?").to_string(),
lbl: v["lbl"].as_str().unwrap_or("?").to_string(),
inputs,
outputs,
color: v["color"].as_i64().unwrap_or(0) as usize,
}))
}
} }
impl BlockView for Block { impl BlockView for Block {
@ -808,27 +893,54 @@ impl BlockArea {
true true
} }
/// Serializes this [BlockArea] to a JSON [Value].
/// Usually called by [BlockFunSnapshot::serialize].
pub fn serialize(&self) -> Value { pub fn serialize(&self) -> Value {
let mut v = json!({}); let mut v = json!({
"size": [self.size.0 as i64, self.size.1 as i64],
"header": self.header,
"auto_shrink": self.auto_shrink,
});
let mut blks = json!([]);
if let Value::Array(blks) = &mut blks {
for ((x, y), b) in self.blocks.iter() {
blks.push(json!({
"x": x,
"y": y,
"block": b.serialize(),
}));
}
}
v["blocks"] = blks;
v v
} }
pub fn deserialize(s: &str) -> Result<Box<BlockArea>, serde_json::Error> { /// Deserializes a from a JSON [Value].
let v: Value = serde_json::from_str(s)?; /// Usually called by [BlockFunSnapshot::deserialize].
pub fn deserialize(v: &Value) -> Result<Box<BlockArea>, serde_json::Error> {
let mut blocks = HashMap::new();
let blocks = HashMap::new(); let blks = &v["blocks"];
let size = (0, 0); if let Value::Array(blks) = blks {
let auto_shrink = false; for b in blks.iter() {
let header = "".to_string(); let x = b["x"].as_i64().unwrap_or(0);
let y = b["y"].as_i64().unwrap_or(0);
blocks.insert((x, y), Block::deserialize(&b["block"])?);
}
}
let mut ba = Box::new(BlockArea { let size = (
blocks, v["size"][0].as_i64().unwrap_or(0) as usize,
origin_map: HashMap::new(), v["size"][1].as_i64().unwrap_or(0) as usize,
size, );
auto_shrink, let auto_shrink = v["auto_shrink"].as_bool().unwrap_or(true);
header, let header = v["header"].as_str().unwrap_or("").to_string();
});
let mut ba =
Box::new(BlockArea { blocks, origin_map: HashMap::new(), size, auto_shrink, header });
ba.update_origin_map(); ba.update_origin_map();
@ -1026,10 +1138,17 @@ impl BlockFunSnapshot {
pub fn deserialize(s: &str) -> Result<BlockFunSnapshot, serde_json::Error> { pub fn deserialize(s: &str) -> Result<BlockFunSnapshot, serde_json::Error> {
let v: Value = serde_json::from_str(s)?; let v: Value = serde_json::from_str(s)?;
let mut areas = vec![]; let mut a = vec![];
let areas = &v["areas"];
if let Value::Array(areas) = areas {
for v in areas.iter() {
a.push(BlockArea::deserialize(v)?);
}
}
Ok(BlockFunSnapshot { Ok(BlockFunSnapshot {
areas, areas: a,
cur_id: v["current_block_id_counter"].as_i64().unwrap_or(0) as usize, cur_id: v["current_block_id_counter"].as_i64().unwrap_or(0) as usize,
}) })
} }
@ -1686,3 +1805,24 @@ impl BlockCodeView for BlockFun {
self.generation self.generation
} }
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn check_blockfun_serialize_empty() {
let dsp_lib = synfx_dsp_jit::get_standard_library();
let lang = crate::blocklang_def::setup_hxdsp_block_language(dsp_lib);
let mut bf = BlockFun::new(lang.clone());
let sn = bf.save_snapshot();
let serialized = sn.serialize();
assert_eq!(serialized, "{\"VERSION\":1,\"areas\":[{\"auto_shrink\":false,\"blocks\":[],\"header\":\"\",\"size\":[16,16]}],\"current_block_id_counter\":0}");
let sn = BlockFunSnapshot::deserialize(&serialized).expect("No deserialization error");
let mut bf2 = BlockFun::new(lang);
let bf2 = bf2.load_snapshot(&sn);
}
}