use crate::capnp_messages::{read_feature, write_feature};
use crate::features_query::{
FeatureRef, GetFeaturesRequest, GetFeaturesResponse, QueryFeatureKind,
};
use ::capnp::message::Builder;
use ::capnp::serialize;
use std::io::Cursor;
fn query_feature_kind_to_capnp(
kind: QueryFeatureKind,
) -> crate::features_query_capnp::QueryFeatureKind {
match kind {
QueryFeatureKind::Route => crate::features_query_capnp::QueryFeatureKind::Route,
QueryFeatureKind::Shape => crate::features_query_capnp::QueryFeatureKind::Shape,
}
}
fn query_feature_kind_from_capnp(
kind: crate::features_query_capnp::QueryFeatureKind,
) -> QueryFeatureKind {
match kind {
crate::features_query_capnp::QueryFeatureKind::Route => QueryFeatureKind::Route,
crate::features_query_capnp::QueryFeatureKind::Shape => QueryFeatureKind::Shape,
}
}
fn write_feature_ref(
builder: &mut crate::features_query_capnp::feature_ref::Builder,
feature_ref: &FeatureRef,
) {
builder.set_id(&feature_ref.id);
builder.set_kind(query_feature_kind_to_capnp(feature_ref.kind));
}
fn read_feature_ref(
reader: crate::features_query_capnp::feature_ref::Reader,
) -> Result<FeatureRef, ::capnp::Error> {
Ok(FeatureRef {
id: reader.get_id()?.to_str()?.to_string(),
kind: query_feature_kind_from_capnp(reader.get_kind()?),
})
}
pub fn serialize_get_features_request(
request: &GetFeaturesRequest,
) -> Result<Vec<u8>, ::capnp::Error> {
let mut message = Builder::new_default();
let mut builder =
message.init_root::<crate::features_query_capnp::get_features_request::Builder>();
let mut refs_builder = builder
.reborrow()
.init_feature_refs(request.feature_refs.len() as u32);
for (i, feature_ref) in request.feature_refs.iter().enumerate() {
let mut ref_builder = refs_builder.reborrow().get(i as u32);
write_feature_ref(&mut ref_builder, feature_ref);
}
let mut buf = Vec::new();
serialize::write_message(&mut buf, &message)?;
Ok(buf)
}
pub fn deserialize_get_features_request(data: &[u8]) -> Result<GetFeaturesRequest, ::capnp::Error> {
let cursor = Cursor::new(data);
let message_reader = serialize::read_message(cursor, ::capnp::message::ReaderOptions::new())?;
let reader =
message_reader.get_root::<crate::features_query_capnp::get_features_request::Reader>()?;
let refs_reader = reader.get_feature_refs()?;
let mut feature_refs = Vec::with_capacity(refs_reader.len() as usize);
for i in 0..refs_reader.len() {
feature_refs.push(read_feature_ref(refs_reader.get(i))?);
}
Ok(GetFeaturesRequest { feature_refs })
}
pub fn serialize_get_features_response(
response: &GetFeaturesResponse,
) -> Result<Vec<u8>, ::capnp::Error> {
let mut message = Builder::new_default();
let mut builder =
message.init_root::<crate::features_query_capnp::get_features_response::Builder>();
let mut items_builder = builder.reborrow().init_items(response.items.len() as u32);
for (i, item) in response.items.iter().enumerate() {
let mut item_builder = items_builder.reborrow().get(i as u32);
write_feature(&mut item_builder, item);
}
let mut buf = Vec::new();
serialize::write_message(&mut buf, &message)?;
Ok(buf)
}
pub fn deserialize_get_features_response(
data: &[u8],
) -> Result<GetFeaturesResponse, ::capnp::Error> {
let cursor = Cursor::new(data);
let message_reader = serialize::read_message(cursor, ::capnp::message::ReaderOptions::new())?;
let reader =
message_reader.get_root::<crate::features_query_capnp::get_features_response::Reader>()?;
let items_reader = reader.get_items()?;
let mut items = Vec::with_capacity(items_reader.len() as usize);
for i in 0..items_reader.len() {
items.push(read_feature(items_reader.get(i))?);
}
Ok(GetFeaturesResponse { items })
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core_model::{AssetIdentity, Feature, LayerRole, ScopeType};
use crate::spatial_types::{
GeoPoint, GeoPose, SpatialData, Wgs84PolygonData, Wgs84Route, Wgs84Shape,
};
#[test]
fn test_get_features_request_roundtrip() {
let original = GetFeaturesRequest {
feature_refs: vec![
FeatureRef {
id: "Route-123".to_string(),
kind: QueryFeatureKind::Route,
},
FeatureRef {
id: "geom-456".to_string(),
kind: QueryFeatureKind::Shape,
},
],
};
let serialized = serialize_get_features_request(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_features_request(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_get_features_response_roundtrip() {
let original = GetFeaturesResponse {
items: vec![
Feature {
identity: AssetIdentity {
id: "route-123".to_string(),
name: "Test Route".to_string(),
rev: 1,
hash: "abc123".to_string(),
},
layer_role: LayerRole::Target,
scope: ScopeType::Fleet,
data: SpatialData::Wgs84Route(Wgs84Route::Path(vec![
GeoPose {
lat_deg: 37.7749,
lon_deg: -122.4194,
altitude_m: 10.0,
heading_deg: 45.0,
},
GeoPose {
lat_deg: 37.7750,
lon_deg: -122.4195,
altitude_m: 10.0,
heading_deg: 90.0,
},
])),
expires_at_ms: 0,
min_z_m: 0.0,
max_z_m: 0.0,
level_id: 0,
},
Feature {
identity: AssetIdentity {
id: "shape-456".to_string(),
name: "Test Shape".to_string(),
rev: 2,
hash: "def456".to_string(),
},
layer_role: LayerRole::WorkArea,
scope: ScopeType::Fleet,
data: SpatialData::Wgs84Shape(Wgs84Shape::Polygon(Wgs84PolygonData {
exterior: vec![
GeoPoint {
lon: -122.4194,
lat: 37.7749,
},
GeoPoint {
lon: -122.4195,
lat: 37.7750,
},
GeoPoint {
lon: -122.4196,
lat: 37.7749,
},
],
holes: vec![],
})),
expires_at_ms: 0,
min_z_m: 0.0,
max_z_m: 100.0,
level_id: 0,
},
],
};
let serialized = serialize_get_features_response(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_features_response(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_empty_request_roundtrip() {
let original = GetFeaturesRequest {
feature_refs: vec![],
};
let serialized = serialize_get_features_request(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_features_request(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_empty_response_roundtrip() {
let original = GetFeaturesResponse { items: vec![] };
let serialized = serialize_get_features_response(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_features_response(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
}