led_rs/
lib.rs

1/// A basic parser for LEd files
2/// See https://deepnight.net/docs/led/json/ for the format
3/// Configured for version 0.2.1 of the editor, version 1 JSON files
4use serde::Deserialize;
5use serde_json::from_str;
6
7pub mod render_helpers;
8
9#[derive(Deserialize, Debug)]
10#[serde(rename_all(deserialize = "camelCase"))]
11pub struct Project {
12    /// Contains the full path to the project JSON, as provided to the macro (using slashes)
13    pub project_file_path: Option<String>,
14
15    /// Contains the directory of the project JSON (using slashes, no trailing slash)
16    pub project_dir: Option<String>,
17
18    /// Project name
19    pub name: String,
20
21    /// Project background color as hex (e.g. #FFFFFF)
22    pub bg_color: String,
23
24    pub json_version: String,
25    pub default_pivot_x: f64,
26    pub default_pivot_y: f64,
27
28    pub levels: Vec<Level>,
29    // pub defs: Definitions, omitted, use the fields on the level layers
30}
31
32impl Project {
33    pub fn parse_json(json: String) -> Result<Self, anyhow::Error> {
34        Ok(from_str(&json)?)
35    }
36}
37
38#[derive(Deserialize, Debug)]
39#[serde(rename_all(deserialize = "camelCase"))]
40pub struct Level {
41    pub identifier: String,
42    pub px_wid: isize,
43    pub px_hei: isize,
44
45    pub layer_instances: Vec<LayerInstance>,
46}
47
48#[derive(Deserialize, Debug)]
49#[serde(rename_all(deserialize = "camelCase"))]
50pub struct LayerInstance {
51    #[serde(rename(deserialize = "__identifier"))]
52    pub identifer: String,
53
54    #[serde(rename(deserialize = "__type"))]
55    pub layer_type: String,
56
57    #[serde(rename(deserialize = "__cWid"))]
58    pub grid_width: usize,
59
60    #[serde(rename(deserialize = "__cHei"))]
61    pub grid_height: usize,
62
63    pub level_id: usize,
64    pub layer_def_uid: usize,
65    pub px_offset_x: isize,
66    pub px_offset_y: isize,
67    pub seed: usize,
68
69    pub int_grid: Vec<IntGridCoordinate>,
70    pub auto_tiles: Vec<AutoTileRule>,
71    pub grid_tiles: Vec<GridTile>,
72    pub entity_instances: Vec<EntityInstance>,
73}
74
75#[derive(Deserialize, Debug)]
76#[serde(rename_all(deserialize = "camelCase"))]
77pub struct IntGridCoordinate {
78    pub coord_id: usize,
79    pub v: usize,
80}
81
82#[derive(Deserialize, Debug)]
83#[serde(rename_all(deserialize = "camelCase"))]
84pub struct AutoTileRule {
85    pub rule_id: usize,
86    pub tiles: Vec<GridTile>,
87}
88
89#[derive(Deserialize, Debug)]
90#[serde(rename_all(deserialize = "camelCase"))]
91pub struct GridTile {
92    pub coord_id: usize,
93    pub tile_id: usize,
94    pub flips: Option<usize>,
95    #[serde(rename(deserialize = "__tileX"))]
96    pub tile_x: usize,
97    #[serde(rename(deserialize = "__tileY"))]
98    pub tile_y: usize,
99}
100
101#[derive(Deserialize, Debug)]
102#[serde(rename_all(deserialize = "camelCase"))]
103pub struct EntityInstance {
104    #[serde(rename(deserialize = "__identifier"))]
105    pub identifier: String,
106
107    #[serde(rename(deserialize = "__cx"))]
108    pub cx: isize,
109
110    #[serde(rename(deserialize = "__cy"))]
111    pub cy: isize,
112
113    pub def_uid: usize,
114    pub x: isize,
115    pub y: isize,
116
117    pub field_instances: Vec<FieldInstanceValue>,
118}
119
120#[derive(Deserialize, Debug)]
121#[serde(tag = "__type")]
122pub enum FieldInstanceValue {
123    Int(ScalarField<isize>),
124    Float(ScalarField<f32>),
125    Bool(ScalarField<bool>),
126    String(ScalarField<String>),
127    Color(ScalarField<String>),
128
129    #[serde(rename = "Array<Int>")]
130    IntArray(ArrayField<isize>),
131    #[serde(rename = "Array<Float>")]
132    FloatArray(ArrayField<f32>),
133    #[serde(rename = "Array<Bool>")]
134    BoolArray(ArrayField<bool>),
135    #[serde(rename = "Array<String>")]
136    StringArray(ArrayField<String>),
137    #[serde(rename = "Array<Color>")]
138    ColorArray(ArrayField<String>),
139}
140
141#[derive(Deserialize, Debug)]
142#[serde(rename_all(deserialize = "camelCase"))]
143pub struct ScalarField<T> {
144    #[serde(rename(deserialize = "__identifier"))]
145    pub identifier: String,
146
147    #[serde(rename(deserialize = "__value"))]
148    pub value: T,
149
150    pub def_uid: usize,
151}
152
153#[derive(Deserialize, Debug)]
154#[serde(rename_all(deserialize = "camelCase"))]
155pub struct ArrayField<T> {
156    #[serde(rename(deserialize = "__identifier"))]
157    pub identifier: String,
158
159    #[serde(rename(deserialize = "__value"))]
160    pub value: Vec<T>,
161
162    pub def_uid: usize,
163}