1use 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 pub project_file_path: Option<String>,
14
15 pub project_dir: Option<String>,
17
18 pub name: String,
20
21 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 }
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}