chore(deps): rand 0.9.4 + compatible sweep + serde_yaml→serde_norway (#966)

Focused Rust dependency-maintenance pass from the 2026-05-23 security/freshness
review. No CVEs; one advisory cleared and one deprecated crate replaced.

- rand 0.9.2 → 0.9.4 (lockfile): clears RUSTSEC-2026-0097 (unsound with a
  custom logger using rand::rng()). Semver-compatible; rand 0.10 is a separate
  major.
- Compatible-update sweep: ~90 lockfile-only patch/minor bumps (bevy 0.18.0→
  0.18.1, clap 4.5→4.6, rayon 1.11→1.12, pathfinding 4.14→4.15, uuid 1.20→1.23,
  zerocopy, serde_json, tracing-subscriber, etc.). cargo test green.
- serde_yaml 0.9 (deprecated/archived upstream) → serde_norway 0.9, an actively
  maintained drop-in fork. In the server it is test-only (poi.rs round-trip,
  trait_modifiers.rs fixture, tests/news_ticker.rs) so it moves to
  dev-dependencies; line-previewer parses dialogue/monologue pool YAML at
  runtime, so it keeps it as a normal dependency. API is identical (from_str/
  to_string).

news_ticker.rs also picks up its share of the #967 clippy sweep (HashSet/HashMap
→ BTree, doc-list indent) since it is the same file as the serde rename.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 11:02:57 +02:00
co-authored by Claude Opus 4.7
parent 88712ba54f
commit 9a10c6ffd6
9 changed files with 419 additions and 218 deletions
+389 -191
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -14,7 +14,6 @@ bevy_tasks = { version = "0.18", features = ["multi_threaded"] }
# systems marked with TODO comments. Active use begins when profiling shows bottlenecks.
rayon = "1"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.9"
ron = "0.8"
rmp-serde = "1"
rand = "0.9"
@@ -40,6 +39,9 @@ default = ["gauntlet"]
gauntlet = []
[dev-dependencies]
# Maintained drop-in fork of the deprecated serde_yaml 0.9 (#966). Test-only:
# the YAML round-trip in poi.rs and the trait-config fixture in trait_modifiers.rs.
serde_norway = "0.9"
# ---------------------------------------------------------------------------
# Explicit test target for the Layer 3 integration module (D-030, ticket #200).
+1 -1
View File
@@ -259,7 +259,7 @@ modifiers:
stage2:
delivery_tags: ["casual_delivery", "gossip_delivery"]
"#;
serde_yaml::from_str(yaml).expect("valid trait config YAML")
serde_norway::from_str(yaml).expect("valid trait config YAML")
}
#[test]
+3 -2
View File
@@ -205,8 +205,9 @@ mod tests {
#[test]
fn poi_serialization_roundtrip() {
let poi = make_poi("med_bay", PoiCategory::Service, PoiVisibility::LineOfSight);
let serialized = serde_yaml::to_string(&poi).expect("serialize");
let deserialized: PointOfInterest = serde_yaml::from_str(&serialized).expect("deserialize");
let serialized = serde_norway::to_string(&poi).expect("serialize");
let deserialized: PointOfInterest =
serde_norway::from_str(&serialized).expect("deserialize");
assert_eq!(deserialized.poi_id, "med_bay");
assert_eq!(deserialized.category, PoiCategory::Service);
}
+10 -10
View File
@@ -4,7 +4,7 @@
//! - D-036: Sova Transit District — The Last Shift bar shows news ticker
//! - D-010 principle 4: ticker rotation must use SimRng (deterministic)
//! - #591: TickerPool loads ticker/the-last-shift.yaml, rotates every 200 ticks,
//! populates current_ticker in ObserverSnapshot when player is in "bar" zone
//! populates current_ticker in ObserverSnapshot when player is in "bar" zone
//!
//! Test structure:
//! - Layer 1 (pure): validate the ticker YAML content (30 headlines, required fields)
@@ -54,7 +54,7 @@ fn ticker_yaml_exists_and_parses() {
let content = std::fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("Failed to read ticker YAML: {}", e));
let _: TickerFile = serde_yaml::from_str(&content)
let _: TickerFile = serde_norway::from_str(&content)
.unwrap_or_else(|e| panic!("Ticker YAML failed to parse: {}\nFile: {:?}", e, path));
}
@@ -69,7 +69,7 @@ fn ticker_yaml_has_30_headlines() {
}
let content = std::fs::read_to_string(&path).expect("read ticker YAML");
let file: TickerFile = serde_yaml::from_str(&content).expect("parse ticker YAML");
let file: TickerFile = serde_norway::from_str(&content).expect("parse ticker YAML");
assert_eq!(
file.headlines.len(),
@@ -88,7 +88,7 @@ fn ticker_yaml_location_is_the_last_shift() {
}
let content = std::fs::read_to_string(&path).expect("read ticker YAML");
let file: TickerFile = serde_yaml::from_str(&content).expect("parse ticker YAML");
let file: TickerFile = serde_norway::from_str(&content).expect("parse ticker YAML");
assert_eq!(
file.location, "the-last-shift",
@@ -108,7 +108,7 @@ fn ticker_yaml_all_headlines_have_required_fields() {
}
let content = std::fs::read_to_string(&path).expect("read ticker YAML");
let file: TickerFile = serde_yaml::from_str(&content).expect("parse ticker YAML");
let file: TickerFile = serde_norway::from_str(&content).expect("parse ticker YAML");
for (i, headline) in file.headlines.iter().enumerate() {
assert!(!headline.id.is_empty(), "Headline[{}] missing id field", i);
@@ -135,9 +135,9 @@ fn ticker_yaml_ids_are_unique() {
}
let content = std::fs::read_to_string(&path).expect("read ticker YAML");
let file: TickerFile = serde_yaml::from_str(&content).expect("parse ticker YAML");
let file: TickerFile = serde_norway::from_str(&content).expect("parse ticker YAML");
let mut seen = std::collections::HashSet::new();
let mut seen = std::collections::BTreeSet::new();
for headline in &file.headlines {
assert!(
seen.insert(headline.id.clone()),
@@ -165,7 +165,7 @@ fn ticker_yaml_categories_are_valid() {
}
let content = std::fs::read_to_string(&path).expect("read ticker YAML");
let file: TickerFile = serde_yaml::from_str(&content).expect("parse ticker YAML");
let file: TickerFile = serde_norway::from_str(&content).expect("parse ticker YAML");
for headline in &file.headlines {
assert!(
@@ -188,9 +188,9 @@ fn ticker_yaml_category_distribution_is_sane() {
}
let content = std::fs::read_to_string(&path).expect("read ticker YAML");
let file: TickerFile = serde_yaml::from_str(&content).expect("parse ticker YAML");
let file: TickerFile = serde_norway::from_str(&content).expect("parse ticker YAML");
let mut counts: std::collections::HashMap<String, usize> = std::collections::HashMap::new();
let mut counts: std::collections::BTreeMap<String, usize> = std::collections::BTreeMap::new();
for headline in &file.headlines {
*counts.entry(headline.category.clone()).or_insert(0) += 1;
}