1use serde::{Deserialize, Serialize};
2use serde_json::to_value;
3use std::collections::HashMap;
4
5use crate::vpx::collection::Collection;
6use crate::vpx::custominfotags::CustomInfoTags;
7use crate::vpx::gamedata::{GameData, GameDataJson};
8use crate::vpx::tableinfo::TableInfo;
9
10#[derive(Serialize, Deserialize)]
11struct CollectionJson {
12 name: String,
13 items: Vec<String>,
14 fire_events: bool,
15 stop_single_events: bool,
16 group_elements: bool,
17}
18
19#[derive(Serialize, Deserialize)]
23struct TableInfoJson {
24 table_name: Option<String>,
25 author_name: Option<String>,
26 table_blurb: Option<String>,
27 table_rules: Option<String>,
28 author_email: Option<String>,
29 release_date: Option<String>,
30 table_save_rev: Option<String>,
31 table_version: Option<String>,
32 author_website: Option<String>,
33 table_save_date: Option<String>,
34 table_description: Option<String>,
35 properties: HashMap<String, String>,
36 properties_order: Vec<String>,
38}
39
40pub fn info_to_json(
41 table_info: &TableInfo,
42 custom_info_tags: &CustomInfoTags,
43) -> serde_json::Value {
44 let info_json = TableInfoJson {
46 table_name: table_info.table_name.clone(),
47 author_name: table_info.author_name.clone(),
48 table_blurb: table_info.table_blurb.clone(),
49 table_rules: table_info.table_rules.clone(),
50 author_email: table_info.author_email.clone(),
51 release_date: table_info.release_date.clone(),
52 table_save_rev: table_info.table_save_rev.clone(),
53 table_version: table_info.table_version.clone(),
54 author_website: table_info.author_website.clone(),
55 table_save_date: table_info.table_save_date.clone(),
56 table_description: table_info.table_description.clone(),
57 properties: table_info.properties.clone(),
58 properties_order: custom_info_tags.clone(),
59 };
60 to_value(info_json).unwrap()
61}
62
63pub fn json_to_info(
64 json: serde_json::Value,
65 screenshot: Option<Vec<u8>>,
66) -> Result<(TableInfo, CustomInfoTags), serde_json::Error> {
67 let info_json: TableInfoJson = serde_json::from_value(json.clone())?;
68 let table_info = TableInfo {
69 table_name: info_json.table_name,
70 author_name: info_json.author_name,
71 screenshot,
72 table_blurb: info_json.table_blurb,
73 table_rules: info_json.table_rules,
74 author_email: info_json.author_email,
75 release_date: info_json.release_date,
76 table_save_rev: info_json.table_save_rev,
77 table_version: info_json.table_version,
78 author_website: info_json.author_website,
79 table_save_date: info_json.table_save_date,
80 table_description: info_json.table_description,
81 properties: info_json.properties,
82 };
83 let custom_info_tags = info_json.properties_order;
84 Ok((table_info, custom_info_tags))
85}
86
87pub fn collections_json(collections: &[Collection]) -> serde_json::Value {
88 let mut collections_json = Vec::new();
89 for collection in collections {
90 let collection_json = CollectionJson {
91 name: collection.name.clone(),
92 items: collection.items.clone(),
93 fire_events: collection.fire_events,
94 stop_single_events: collection.stop_single_events,
95 group_elements: collection.group_elements,
96 };
97 collections_json.push(collection_json);
98 }
99 to_value(collections_json).unwrap()
100}
101
102pub fn json_to_collections(json: serde_json::Value) -> Result<Vec<Collection>, serde_json::Error> {
103 let collections_json: Vec<CollectionJson> = serde_json::from_value(json)?;
104 let mut collections = Vec::new();
105 for collection_json in collections_json {
106 let collection = Collection {
107 name: collection_json.name,
108 items: collection_json.items,
109 fire_events: collection_json.fire_events,
110 stop_single_events: collection_json.stop_single_events,
111 group_elements: collection_json.group_elements,
112 };
113 collections.push(collection);
114 }
115 Ok(collections)
116}
117
118pub fn game_data_to_json(game_data: &GameData) -> serde_json::Value {
119 let game_data_json = GameDataJson::from_game_data(game_data);
120 to_value(game_data_json).unwrap()
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126 use crate::vpx::collection::Collection;
127 use crate::vpx::custominfotags::CustomInfoTags;
128 use crate::vpx::gamedata::GameData;
129 use crate::vpx::tableinfo::TableInfo;
130 use serde_json::Value;
131
132 #[test]
133 fn test_info_to_json() {
134 let table_info = TableInfo::default();
135 let custom_info_tags = CustomInfoTags::default();
136 let json = info_to_json(&table_info, &custom_info_tags);
137 let (table_info2, custom_info_tags2) = json_to_info(json, None).unwrap();
138 assert_eq!(table_info, table_info2);
139 assert_eq!(custom_info_tags, custom_info_tags2);
140 }
141
142 #[test]
143 fn test_collections_to_json() {
144 let collections = vec![
145 Collection {
146 name: "collection1".to_string(),
147 items: vec!["item1".to_string(), "item2".to_string()],
148 fire_events: true,
149 stop_single_events: false,
150 group_elements: true,
151 },
152 Collection {
153 name: "collection2".to_string(),
154 items: vec!["item3".to_string(), "item4".to_string()],
155 fire_events: false,
156 stop_single_events: true,
157 group_elements: false,
158 },
159 ];
160 let json = collections_json(&collections);
161 let collections2 = json_to_collections(json).unwrap();
162 assert_eq!(collections, collections2);
163 }
164
165 #[test]
166 fn test_game_data_to_json() {
167 let game_data = GameData::default();
168 let json = game_data_to_json(&game_data);
169 let map = json.as_object().unwrap();
171 let name = map.get("name").unwrap();
172 assert_eq!(name, &Value::String("Table1".to_string()));
173 }
174}