Skip to content

Commit 4209cf7

Browse files
committed
refactor save to use BlueprintType
1 parent 2c71ce6 commit 4209cf7

3 files changed

Lines changed: 111 additions & 83 deletions

File tree

src/blueprint.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ pub(crate) enum BlueprintType<T: Borrow<serde_json::Value>> {
5252
DeconstructionPlanner(T),
5353
}
5454

55+
impl BlueprintType<&serde_json::Value> {
56+
pub fn new(json: &serde_json::Value) -> BlueprintType<&serde_json::Value> {
57+
let json = match json {
58+
serde_json::Value::Object(json) => json,
59+
_ => panic!("blueprint entry should be an object, got {json:?}"),
60+
};
61+
62+
if json.contains_key("blueprint") {
63+
BlueprintType::Blueprint(&json["blueprint"])
64+
} else if json.contains_key("blueprint_book") {
65+
BlueprintType::BlueprintBook(&json["blueprint_book"])
66+
} else if json.contains_key("upgrade_planner") {
67+
BlueprintType::UpgradePlanner(&json["upgrade_planner"])
68+
} else if json.contains_key("deconstruction_planner") {
69+
BlueprintType::DeconstructionPlanner(&json["deconstruction_planner"])
70+
} else {
71+
panic!("blueprint has unknown type: {:?}", json.keys());
72+
}
73+
}
74+
}
75+
5576
impl BlueprintType<&mut serde_json::Value> {
5677
pub fn new(json: &mut serde_json::Value) -> BlueprintType<&mut serde_json::Value> {
5778
let json = match json {
@@ -95,6 +116,22 @@ impl BlueprintType<&mut serde_json::Value> {
95116
}
96117
}
97118

119+
impl<T: Borrow<serde_json::Value>> BlueprintType<T> {
120+
pub(crate) fn any(&self) -> &serde_json::Value {
121+
match self {
122+
BlueprintType::Blueprint(value) => value,
123+
BlueprintType::BlueprintBook(value) => value,
124+
BlueprintType::UpgradePlanner(value) => value,
125+
BlueprintType::DeconstructionPlanner(value) => value,
126+
}
127+
.borrow()
128+
}
129+
130+
pub(crate) fn label(&self) -> Option<&str> {
131+
self.any().get("label")?.as_str()
132+
}
133+
}
134+
98135
fn set_tag_in_string(description: String, tag: &str, value: &str) -> String {
99136
let start_offset = if description.starts_with(&format!("{tag}:")) {
100137
0

src/load.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub(crate) fn stamp(json: &mut serde_json::Value, path: &Path) {
107107
let id = repo
108108
.head_id()
109109
.unwrap_or_else(|e| panic!("error: couldn't get HEAD commit: {e}"));
110-
let mut bp = blueprint::BlueprintType::new(json);
110+
let mut bp = blueprint::BlueprintType::<&mut serde_json::Value>::new(json);
111111
bp.set_tag_in_description("last_commit", &format!("{id}"));
112112
}
113113

src/save.rs

Lines changed: 73 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use std::{
55
path::{Path, PathBuf},
66
};
77

8+
use crate::blueprint::BlueprintType;
9+
810
fn format_tag(
911
typ: &str,
1012
name: Option<&serde_json::Value>,
@@ -48,98 +50,87 @@ fn unique_strings(iter: impl Iterator<Item = String>) -> impl Iterator<Item = St
4850

4951
fn compute_name(json: &serde_json::Value) -> String {
5052
let mut name = String::new();
51-
if let Some(thing) = json
52-
.get("blueprint")
53-
.or(json.get("blueprint_book"))
54-
.or(json.get("upgrade_planner"))
55-
.or(json.get("deconstruction_planner"))
53+
let bp = BlueprintType::<&serde_json::Value>::new(json);
54+
if let Some(label) = bp.label() {
55+
name = label.to_owned();
56+
} else if let Some(icons) = bp.any().get("icons").or(bp
57+
.any()
58+
.get("settings")
59+
.and_then(|settings| settings.get("icons")))
60+
&& let Some(icons) = icons.as_array()
5661
{
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);
62+
for icon in icons {
63+
if let Some(signal) = icon.get("signal")
64+
&& let Some(signal_name) = format_icon_tag(signal)
65+
{
66+
if !name.is_empty() {
67+
name.push(' ');
7468
}
69+
name.push_str(&signal_name);
7570
}
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);
71+
}
72+
} else if let BlueprintType::DeconstructionPlanner(blueprint) = bp
73+
&& let Some(settings) = blueprint.get("settings")
74+
{
75+
let entities = settings.get("entity_filters");
76+
let entities = entities
77+
.iter()
78+
.flat_map(|e| e.as_array())
79+
.flatten()
80+
.flat_map(format_entity_tag);
8581

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);
82+
let tiles = settings.get("tile_filters");
83+
let tiles = tiles
84+
.iter()
85+
.flat_map(|e| e.as_array())
86+
.flatten()
87+
.flat_map(format_tile_tag);
9288

93-
let mut iter = entities.chain(tiles).fuse();
89+
let mut iter = entities.chain(tiles).fuse();
9490

95-
for name_part in (&mut iter).take(4) {
96-
if !name.is_empty() {
97-
name.push(' ');
98-
}
99-
name.push_str(&name_part);
100-
}
101-
if iter.next().is_some() {
102-
name.push('…');
91+
for name_part in (&mut iter).take(4) {
92+
if !name.is_empty() {
93+
name.push(' ');
10394
}
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) {
132-
if !name.is_empty() {
133-
name.push(' ');
95+
name.push_str(&name_part);
96+
}
97+
if iter.next().is_some() {
98+
name.push('…');
99+
}
100+
} else if let BlueprintType::UpgradePlanner(blueprint) = bp
101+
&& let Some(settings) = blueprint.get("settings")
102+
&& let Some(mappers) = settings.get("mappers")
103+
&& let Some(mappers) = mappers.as_array()
104+
{
105+
let mut iter = unique_strings(mappers.iter().flat_map(|mapper| mapper.get("to")).flat_map(
106+
|to| {
107+
let typ = to.get("type");
108+
if let Some(typ) = typ
109+
&& let Some(typ) = typ.as_str()
110+
&& let Some(name_part) = format_tag(typ, to.get("name"), to.get("quality"))
111+
{
112+
Some(name_part)
113+
} else if let Some(name_part) = to.get("name")
114+
&& let Some(name_part) = name_part.as_str()
115+
{
116+
Some(name_part.to_owned())
117+
} else {
118+
None
134119
}
135-
name.push_str(&name_part);
136-
}
137-
if iter.next().is_some() {
138-
name.push('…');
139-
}
120+
},
121+
))
122+
.fuse();
123+
for name_part in (&mut iter).take(4) {
140124
if !name.is_empty() {
141-
name = format!("Upgrade {name}");
125+
name.push(' ');
142126
}
127+
name.push_str(&name_part);
128+
}
129+
if iter.next().is_some() {
130+
name.push('…');
131+
}
132+
if !name.is_empty() {
133+
name = format!("Upgrade {name}");
143134
}
144135
}
145136

0 commit comments

Comments
 (0)