@@ -5,96 +5,152 @@ use std::{
55 path:: { Path , PathBuf } ,
66} ;
77
8- pub fn save ( mut json : serde_json:: Value , dir : Option < & Path > ) {
8+ fn format_tag (
9+ typ : & str ,
10+ name : Option < & serde_json:: Value > ,
11+ quality : Option < & serde_json:: Value > ,
12+ ) -> Option < String > {
13+ let name = name?. as_str ( ) ?;
14+ let quality_suffix = if let Some ( quality) = quality
15+ && let Some ( quality) = quality. as_str ( )
16+ && quality != "normal"
17+ {
18+ format ! ( ",quality={quality}" )
19+ } else {
20+ String :: new ( )
21+ } ;
22+ Some ( format ! ( "[{typ}={name}{quality_suffix}]" ) )
23+ }
24+
25+ fn format_entity_tag ( entity : & serde_json:: Value ) -> Option < String > {
26+ format_tag ( "entity" , entity. get ( "name" ) , entity. get ( "quality" ) )
27+ }
28+
29+ fn format_icon_tag ( icon : & serde_json:: Value ) -> Option < String > {
30+ format_tag ( "icon" , icon. get ( "name" ) , icon. get ( "quality" ) )
31+ }
32+
33+ fn format_tile_tag ( tile : & serde_json:: Value ) -> Option < String > {
34+ format_tag ( "tile" , tile. get ( "name" ) , tile. get ( "quality" ) )
35+ }
36+
37+ fn unique_strings ( iter : impl Iterator < Item = String > ) -> impl Iterator < Item = String > {
38+ let mut seen: std:: collections:: HashSet < String > = std:: collections:: HashSet :: new ( ) ;
39+ iter. flat_map ( move |s| {
40+ if seen. contains ( & s) {
41+ None
42+ } else {
43+ seen. insert ( s. clone ( ) ) ;
44+ Some ( s)
45+ }
46+ } )
47+ }
48+
49+ fn compute_name ( json : & serde_json:: Value ) -> String {
950 let mut name = String :: new ( ) ;
1051 if let Some ( thing) = json
1152 . get ( "blueprint" )
1253 . or ( json. get ( "blueprint_book" ) )
1354 . or ( json. get ( "upgrade_planner" ) )
1455 . or ( json. get ( "deconstruction_planner" ) )
15- && let Some ( label) = thing. get ( "label" )
16- && let Some ( label) = label. as_str ( )
1756 {
18- name = label. to_owned ( ) ;
19- } else if let Some ( blueprint) = json. get ( "blueprint" )
20- && let Some ( icons) = blueprint. get ( "icons" )
21- && let Some ( icons) = icons. as_array ( )
22- {
23- for icon in icons {
24- if let Some ( signal) = icon. get ( "signal" )
25- && let Some ( signal_name) = signal. get ( "name" )
26- && let Some ( signal_name) = signal_name. as_str ( )
27- {
57+ if let Some ( label) = thing. get ( "label" )
58+ && let Some ( label) = label. as_str ( )
59+ {
60+ name = label. to_owned ( ) ;
61+ } else if let Some ( icons) = thing. get ( "icons" ) . or ( thing
62+ . get ( "settings" )
63+ . and_then ( |settings| settings. get ( "icons" ) ) )
64+ && let Some ( icons) = icons. as_array ( )
65+ {
66+ for icon in icons {
67+ if let Some ( signal) = icon. get ( "signal" )
68+ && let Some ( signal_name) = format_icon_tag ( signal)
69+ {
70+ if !name. is_empty ( ) {
71+ name. push ( ' ' ) ;
72+ }
73+ name. push_str ( & signal_name) ;
74+ }
75+ }
76+ } else if let Some ( blueprint) = json. get ( "deconstruction_planner" )
77+ && let Some ( settings) = blueprint. get ( "settings" )
78+ {
79+ let entities = settings. get ( "entity_filters" ) ;
80+ let entities = entities
81+ . iter ( )
82+ . flat_map ( |e| e. as_array ( ) )
83+ . flatten ( )
84+ . flat_map ( format_entity_tag) ;
85+
86+ let tiles = settings. get ( "tile_filters" ) ;
87+ let tiles = tiles
88+ . iter ( )
89+ . flat_map ( |e| e. as_array ( ) )
90+ . flatten ( )
91+ . flat_map ( format_tile_tag) ;
92+
93+ let mut iter = entities. chain ( tiles) . fuse ( ) ;
94+
95+ for name_part in ( & mut iter) . take ( 4 ) {
2896 if !name. is_empty ( ) {
2997 name. push ( ' ' ) ;
3098 }
31- name. push_str ( signal_name ) ;
99+ name. push_str ( & name_part ) ;
32100 }
33- }
34- } else if let Some ( blueprint) = json. get ( "deconstruction_planner" )
35- && let Some ( settings) = blueprint. get ( "settings" )
36- {
37- let entities = settings. get ( "entity_filters" ) ;
38- let entities = entities
39- . iter ( )
40- . flat_map ( |e| e. as_array ( ) )
41- . flatten ( )
42- . flat_map ( |e| e. get ( "name" ) )
43- . flat_map ( |e| e. as_str ( ) )
44- . map ( |entity_name| format ! ( "[entity={entity_name}]" ) ) ;
45-
46- let tiles = settings. get ( "tile_filters" ) ;
47- let tiles = tiles
48- . iter ( )
49- . flat_map ( |e| e. as_array ( ) )
50- . flatten ( )
51- . flat_map ( |e| e. get ( "name" ) )
52- . flat_map ( |e| e. as_str ( ) )
53- . map ( |tile_name| format ! ( "[tile={tile_name}]" ) ) ;
54-
55- let mut iter = entities. chain ( tiles) . fuse ( ) ;
56-
57- for name_part in ( & mut iter) . take ( 4 ) {
58- if !name. is_empty ( ) {
59- name. push ( ' ' ) ;
101+ if iter. next ( ) . is_some ( ) {
102+ name. push_str ( " …" ) ;
60103 }
61- name. push_str ( & name_part) ;
62- }
63- if iter. next ( ) . is_some ( ) {
64- name. push_str ( " …" ) ;
65- }
66- } else if let Some ( blueprint) = json. get ( "upgrade_planner" )
67- && let Some ( settings) = blueprint. get ( "settings" )
68- && let Some ( mappers) = settings. get ( "mappers" )
69- && let Some ( mappers) = mappers. as_array ( )
70- {
71- let mut iter = mappers. iter ( ) . fuse ( ) ;
72- for mapper in ( & mut iter) . take ( 4 ) {
73- if let Some ( to) = mapper. get ( "to" )
74- && let Some ( name_part) = to. get ( "name" )
75- && let Some ( name_part) = name_part. as_str ( )
76- {
104+ } else if let Some ( blueprint) = json. get ( "upgrade_planner" )
105+ && let Some ( settings) = blueprint. get ( "settings" )
106+ && let Some ( mappers) = settings. get ( "mappers" )
107+ && let Some ( mappers) = mappers. as_array ( )
108+ {
109+ let mut iter = unique_strings (
110+ mappers
111+ . iter ( )
112+ . flat_map ( |mapper| mapper. get ( "to" ) )
113+ . flat_map ( |to| {
114+ let typ = to. get ( "type" ) ;
115+ if let Some ( typ) = typ
116+ && let Some ( typ) = typ. as_str ( )
117+ && let Some ( name_part) =
118+ format_tag ( typ, to. get ( "name" ) , to. get ( "quality" ) )
119+ {
120+ Some ( name_part)
121+ } else if let Some ( name_part) = to. get ( "name" )
122+ && let Some ( name_part) = name_part. as_str ( )
123+ {
124+ Some ( name_part. to_owned ( ) )
125+ } else {
126+ None
127+ }
128+ } ) ,
129+ )
130+ . fuse ( ) ;
131+ for name_part in ( & mut iter) . take ( 4 ) {
77132 if !name. is_empty ( ) {
78133 name. push ( ' ' ) ;
79134 }
80- if let Some ( typ) = to. get ( "type" )
81- && let Some ( typ) = typ. as_str ( )
82- && typ == "entity"
83- {
84- name. push_str ( & format ! ( "[entity={name_part}]" ) ) ;
85- } else {
86- name. push_str ( & name_part) ;
87- }
135+ name. push_str ( & name_part) ;
136+ }
137+ if iter. next ( ) . is_some ( ) {
138+ name. push_str ( " …" ) ;
139+ }
140+ if !name. is_empty ( ) {
141+ name = format ! ( "Upgrade {name}" ) ;
88142 }
89- }
90- if !name. is_empty ( ) {
91- name = format ! ( "Upgrade {name}" ) ;
92143 }
93144 }
94145
95146 if name. is_empty ( ) {
96147 name = "Untitled" . to_owned ( )
97148 } ;
149+ name
150+ }
151+
152+ pub fn save ( mut json : serde_json:: Value , dir : Option < & Path > ) {
153+ let mut name = compute_name ( & json) ;
98154
99155 if let Some ( index) = json. get_mut ( "index" )
100156 && let Some ( index) = index. as_number ( )
@@ -173,9 +229,9 @@ mod tests {
173229 let json = serde_json:: Value :: from_str ( & json) . expect ( "should contain valid json" ) ;
174230 save ( json. clone ( ) , Some ( dir. path ( ) ) ) ;
175231 let files = read_dir_unwrap ( dir. path ( ) ) ;
176- assert_eq ! ( files, & [ "selector-combinator.json" ] ) ;
232+ assert_eq ! ( files, & [ "[icon= selector-combinator] .json" ] ) ;
177233 let written_json =
178- std:: fs:: read_to_string ( dir. path ( ) . join ( "selector-combinator.json" ) ) . unwrap ( ) ;
234+ std:: fs:: read_to_string ( dir. path ( ) . join ( "[icon= selector-combinator] .json" ) ) . unwrap ( ) ;
179235 let written_json = serde_json:: Value :: from_str ( & written_json) . unwrap ( ) ;
180236 assert_eq ! ( written_json, json) ;
181237 }
@@ -192,7 +248,7 @@ mod tests {
192248 let subfiles = read_dir_unwrap ( & dir. path ( ) . join ( "Untitled" ) ) ;
193249 assert_eq ! ( subfiles, [ "0 BP Name 1.json" , "1 Nested Book" , "book.json" ] ) ;
194250 let subsubfiles = read_dir_unwrap ( & dir. path ( ) . join ( "Untitled/1 Nested Book" ) ) ;
195- assert_eq ! ( subsubfiles, [ "6 bulk-inserter.json" , "book.json" ] ) ;
251+ assert_eq ! ( subsubfiles, [ "6 [icon= bulk-inserter] .json" , "book.json" ] ) ;
196252
197253 // TODO: when load is implemented, test that it can load everything back properly.
198254 }
@@ -229,4 +285,31 @@ mod tests {
229285 let written_json = serde_json:: Value :: from_str ( & written_json) . unwrap ( ) ;
230286 assert_eq ! ( written_json, json) ;
231287 }
288+
289+ #[ test]
290+ fn test_dedupe_names_upgrade_planner ( ) {
291+ let bp = "0eNq1UMsKwjAQ/Jc9V5A+LA34JSIS2rUGmt2YbNVS8u8mYK968jaPZXaYFWY3ej3gxU2aCD2oFQKKGBpDxlY7hz7B0wpXzzZrsjgEBUhiZIECSNvMn8wD0q6/YZCk3mc9ZV8Bsbd6SlLP1mmvhdMbOEIsQPhLYBDE6ZOXbg0N+AK1j8XPKsbz/4vU8ZyJYGqyzbjbZizgkWYzTKCaQ9nVXde0VVPVbRnjGw8nfKM=" ;
292+ let json = crate :: blueprint:: blueprint_to_json ( bp) ;
293+ let json = serde_json:: Value :: from_str ( & json) . expect ( "should contain valid json" ) ;
294+ assert_eq ! ( compute_name( & json) , "Upgrade [entity=steel-chest]" )
295+ }
296+
297+ #[ test]
298+ fn test_upgrade_remove_module ( ) {
299+ let bp = "0eNp1js0KwjAQhN9lzy1IfywN+CQiEsxaAtlkTbZiKXl3E7BHbzPfDrOzw8pL1Abv7LT3GEHtkFDE+iVVTZoZY5HXHZ4xUGWyMYICK0jQgNdUXWJE01Iwq8NCX6t2VrZy8CGSdgU9ArGOWkJ5AhfIDUj4W4fEsv3q2uSC1Lz1Bj+gTvlWTc2rY3977G/gXfba4EGN524e5nmc+rEfpi7nL1TiT8I=" ;
300+ let json = crate :: blueprint:: blueprint_to_json ( bp) ;
301+ let json = serde_json:: Value :: from_str ( & json) . expect ( "should contain valid json" ) ;
302+ assert_eq ! ( compute_name( & json) , "Upgrade [item=empty-module-slot]" )
303+ }
304+
305+ #[ test]
306+ fn test_upgrade_quality ( ) {
307+ let bp = "0eNqVT1sKwjAQvMt+V5A+LA14EhHZtmsNdDcx3Yql5O4miAfwbx7M7M4Oq58CjnTzM4pQALPDQqpWpiVjRu8pJHjZ4R4cZ003T2CARK1uUIAgZ95bNzyQ+1RSwHPFObsGxAXGOUmDY48B1aUjcIZYgLr/61ZJPewk562M9AZzjNdMlDj73z2H354CXul/mwKmOZVd3XVNWzVV3ZYxfgDMH1WE" ;
308+ let json = crate :: blueprint:: blueprint_to_json ( bp) ;
309+ let json = serde_json:: Value :: from_str ( & json) . expect ( "should contain valid json" ) ;
310+ assert_eq ! (
311+ compute_name( & json) ,
312+ "Upgrade [entity=biochamber,quality=uncommon]"
313+ )
314+ }
232315}
0 commit comments