bevy_yoleck/
level_files_upgrading.rs

1use bevy::prelude::*;
2
3/// Upgrade a level file to the most recent Yoleck level format
4pub fn upgrade_level_file(mut level: serde_json::Value) -> Result<serde_json::Value> {
5    let parts = level
6        .as_array_mut()
7        .ok_or_else(|| "Level file must be an array")?;
8    let mut format_version = parts
9        .first()
10        .ok_or_else(|| "Level file array must not be empty")?
11        .as_object()
12        .ok_or_else(|| "Level file header must be an object")?
13        .get("format_version")
14        .ok_or_else(|| "Level file header must have a `format_version` field")?
15        .as_u64()
16        .ok_or_else(|| "`format_version` must be a non-negative number")?;
17
18    for (upgrade_to, upgrade_fn) in [(2, upgrade_level_file_1_to_2)] {
19        if format_version < upgrade_to {
20            upgrade_fn(parts)?;
21            format_version = upgrade_to;
22        }
23    }
24
25    parts[0].as_object_mut().expect("already verified")["format_version"] = format_version.into();
26
27    Ok(level)
28}
29
30fn upgrade_level_file_1_to_2(parts: &mut [serde_json::Value]) -> Result<()> {
31    let header = parts
32        .get_mut(0)
33        .ok_or_else(|| "Level file must have header as first element")?
34        .as_object_mut()
35        .ok_or_else(|| "Header must be object")?;
36    header.insert("app_format_version".to_owned(), 0.into());
37
38    let entities = parts
39        .get_mut(2)
40        .ok_or_else(|| "Level file must have entities list as third element")?
41        .as_array_mut()
42        .ok_or_else(|| "Entity list must be array")?;
43
44    for entity in entities.iter_mut() {
45        let entity_type = entity
46            .pointer("/0/type")
47            .ok_or_else(|| "Entity must have a header with a `type` field")?
48            .as_str()
49            .ok_or_else(|| "Entity `type` must be a string")?
50            .to_owned();
51        let entity_data = entity.get_mut(1).ok_or_else(|| "Entity must have data")?;
52        let orig_data = entity_data.take();
53        *entity_data = serde_json::Value::Object(Default::default());
54        entity_data[entity_type] = orig_data;
55    }
56    Ok(())
57}