feat(client): atlas layer-stream codec — encode request / decode response (#960, D-225)
Client half of the layer-stream protocol (codec only; transport wiring next).
- protocol.gd: encode_atlas_layer_request (bare {body_id, up_to} map so the
server demux routes it to the proxy, not the PlayerInput array) and
decode_atlas_layer_response (-> {body_id, status, error, layer1}; returns null
for non-atlas frames, e.g. a snapshot, so receive_bytes can disambiguate).
- gen_fixtures.rs: cross-language fixtures (atlas_response_ready/pending/
not_found) from real rmp_serde output, matching the test_protocol.gd pattern.
- test_protocol.gd: 5 tests decode the fixtures + verify a snapshot is not
mistaken for a response + the request encodes to the right shape. 68/68 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
//! Generate MessagePack fixture files for cross-language testing (D-030 Layer 1).
|
||||
//! Run with: cargo test --test gen_fixtures -- --ignored
|
||||
|
||||
use settled_reach_server::atlas::body_world_state::{DrainageBasin, RiverNetwork};
|
||||
use settled_reach_server::atlas::layer1::Layer1Output;
|
||||
use settled_reach_server::atlas::layer_proxy::{AtlasLayerResponse, AtlasLayerStatus};
|
||||
use settled_reach_server::bridge::types::*;
|
||||
use settled_reach_server::simulation::generator::{
|
||||
AttractorType, GeographicAttractor, SubBiomeVariant,
|
||||
};
|
||||
use settled_reach_server::simulation::poi::PoiCategory;
|
||||
use settled_reach_server::simulation::time::{DayPhase, TickRate};
|
||||
use std::fs;
|
||||
@@ -529,3 +535,60 @@ fn generate_snapshot_with_bookmark_catalog() {
|
||||
rmp_serde::to_vec_named(&snapshot).expect("serialize snapshot_with_bookmark_catalog");
|
||||
write_fixture("snapshot_with_bookmark_catalog", &bytes);
|
||||
}
|
||||
|
||||
/// Atlas layer-stream responses (#969, D-225) — the client decodes these to
|
||||
/// render the per-layer Atlas overlays (#960). Covers Ready (with a small
|
||||
/// Layer1Output), Pending, and NotFound.
|
||||
#[test]
|
||||
#[ignore] // Run manually: cargo test --test gen_fixtures -- --ignored
|
||||
fn generate_atlas_layer_response_fixtures() {
|
||||
let layer1 = Layer1Output {
|
||||
body_id: "GJ1c".into(),
|
||||
river_network: RiverNetwork {
|
||||
river_cells: vec![(12, 58), (12, 59)],
|
||||
confluences: vec![],
|
||||
mouths: vec![(12, 58)],
|
||||
},
|
||||
drainage_basins: vec![DrainageBasin {
|
||||
basin_id: 1,
|
||||
boundary: vec![(0, 0), (0, 10), (10, 10), (10, 0)],
|
||||
area_pct: 0.42,
|
||||
}],
|
||||
attractors: vec![GeographicAttractor {
|
||||
position: (12, 58),
|
||||
attractor_type: AttractorType::CoastalAccess,
|
||||
strength: 0.9,
|
||||
sub_biome: SubBiomeVariant::CoastalLowland,
|
||||
terrain_modification_cost: 1.7,
|
||||
}],
|
||||
};
|
||||
let ready = AtlasLayerResponse {
|
||||
body_id: "GJ1c".into(),
|
||||
status: AtlasLayerStatus::Ready,
|
||||
layer1: Some(layer1),
|
||||
};
|
||||
write_fixture(
|
||||
"atlas_response_ready",
|
||||
&rmp_serde::to_vec_named(&ready).unwrap(),
|
||||
);
|
||||
|
||||
let pending = AtlasLayerResponse {
|
||||
body_id: "GJ1c".into(),
|
||||
status: AtlasLayerStatus::Pending,
|
||||
layer1: None,
|
||||
};
|
||||
write_fixture(
|
||||
"atlas_response_pending",
|
||||
&rmp_serde::to_vec_named(&pending).unwrap(),
|
||||
);
|
||||
|
||||
let not_found = AtlasLayerResponse {
|
||||
body_id: "ghost".into(),
|
||||
status: AtlasLayerStatus::NotFound,
|
||||
layer1: None,
|
||||
};
|
||||
write_fixture(
|
||||
"atlas_response_not_found",
|
||||
&rmp_serde::to_vec_named(¬_found).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user