use crate::core_model::Value;
use crate::settings_query::{GetSettingsRequest, GetSettingsResponse, SettingItem};
use ::capnp::message::Builder;
use ::capnp::serialize;
use std::io::Cursor;
fn write_value(builder: &mut crate::messages_capnp::value::Builder, value: &Value) {
match value {
Value::String(s) => builder.set_string(s),
Value::Int(i) => builder.set_int(*i),
Value::Number(n) => builder.set_number(*n),
Value::Bool(b) => builder.set_bool(*b),
Value::Enum(s) => builder.set_enum(s),
}
}
fn read_value(reader: crate::messages_capnp::value::Reader) -> Result<Value, ::capnp::Error> {
match reader.which()? {
crate::messages_capnp::value::String(Ok(s)) => Ok(Value::String(s.to_str()?.to_string())),
crate::messages_capnp::value::String(Err(e)) => Err(e),
crate::messages_capnp::value::Int(i) => Ok(Value::Int(i)),
crate::messages_capnp::value::Number(n) => Ok(Value::Number(n)),
crate::messages_capnp::value::Bool(b) => Ok(Value::Bool(b)),
crate::messages_capnp::value::Enum(Ok(s)) => Ok(Value::Enum(s.to_str()?.to_string())),
crate::messages_capnp::value::Enum(Err(e)) => Err(e),
}
}
fn write_setting_item(
builder: &mut crate::settings_query_capnp::setting_item::Builder,
item: &SettingItem,
) {
builder.set_key(&item.key);
let mut value_builder = builder.reborrow().init_value();
write_value(&mut value_builder, &item.value);
builder.set_updated_at_ms(item.updated_at_ms);
builder.set_updated_by(&item.updated_by);
}
fn read_setting_item(
reader: crate::settings_query_capnp::setting_item::Reader,
) -> Result<SettingItem, ::capnp::Error> {
Ok(SettingItem {
key: reader.get_key()?.to_str()?.to_string(),
value: read_value(reader.get_value()?)?,
updated_at_ms: reader.get_updated_at_ms(),
updated_by: reader.get_updated_by()?.to_str()?.to_string(),
})
}
pub fn serialize_get_settings_request(
request: &GetSettingsRequest,
) -> Result<Vec<u8>, ::capnp::Error> {
let mut message = Builder::new_default();
let mut builder =
message.init_root::<crate::settings_query_capnp::get_settings_request::Builder>();
let mut keys_builder = builder.reborrow().init_keys(request.keys.len() as u32);
for (i, key) in request.keys.iter().enumerate() {
keys_builder.set(i as u32, key);
}
let mut buf = Vec::new();
serialize::write_message(&mut buf, &message)?;
Ok(buf)
}
pub fn deserialize_get_settings_request(data: &[u8]) -> Result<GetSettingsRequest, ::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::settings_query_capnp::get_settings_request::Reader>()?;
let keys_reader = reader.get_keys()?;
let mut keys = Vec::with_capacity(keys_reader.len() as usize);
for i in 0..keys_reader.len() {
keys.push(keys_reader.get(i)?.to_str()?.to_string());
}
Ok(GetSettingsRequest { keys })
}
pub fn serialize_get_settings_response(
response: &GetSettingsResponse,
) -> Result<Vec<u8>, ::capnp::Error> {
let mut message = Builder::new_default();
let mut builder =
message.init_root::<crate::settings_query_capnp::get_settings_response::Builder>();
let mut settings_builder = builder
.reborrow()
.init_settings(response.settings.len() as u32);
for (i, item) in response.settings.iter().enumerate() {
let mut item_builder = settings_builder.reborrow().get(i as u32);
write_setting_item(&mut item_builder, item);
}
let mut not_found_builder = builder
.reborrow()
.init_not_found(response.not_found.len() as u32);
for (i, key) in response.not_found.iter().enumerate() {
not_found_builder.set(i as u32, key);
}
let mut buf = Vec::new();
serialize::write_message(&mut buf, &message)?;
Ok(buf)
}
pub fn deserialize_get_settings_response(
data: &[u8],
) -> Result<GetSettingsResponse, ::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::settings_query_capnp::get_settings_response::Reader>()?;
let settings_reader = reader.get_settings()?;
let mut settings = Vec::with_capacity(settings_reader.len() as usize);
for i in 0..settings_reader.len() {
settings.push(read_setting_item(settings_reader.get(i))?);
}
let not_found_reader = reader.get_not_found()?;
let mut not_found = Vec::with_capacity(not_found_reader.len() as usize);
for i in 0..not_found_reader.len() {
not_found.push(not_found_reader.get(i)?.to_str()?.to_string());
}
Ok(GetSettingsResponse {
settings,
not_found,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_settings_request_roundtrip() {
let original = GetSettingsRequest {
keys: vec![
"robot.speed_limit".to_string(),
"robot.name".to_string(),
"debug.enabled".to_string(),
],
};
let serialized = serialize_get_settings_request(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_settings_request(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_get_settings_request_empty_roundtrip() {
let original = GetSettingsRequest { keys: vec![] };
let serialized = serialize_get_settings_request(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_settings_request(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_get_settings_response_roundtrip() {
let original = GetSettingsResponse {
settings: vec![
SettingItem {
key: "robot.speed_limit".to_string(),
value: Value::Number(1.5),
updated_at_ms: 1706800000000,
updated_by: "fleet_manager".to_string(),
},
SettingItem {
key: "robot.name".to_string(),
value: Value::String("Robot-42".to_string()),
updated_at_ms: 1706799000000,
updated_by: "".to_string(),
},
SettingItem {
key: "debug.enabled".to_string(),
value: Value::Bool(true),
updated_at_ms: 1706798000000,
updated_by: "admin".to_string(),
},
SettingItem {
key: "robot.max_retries".to_string(),
value: Value::Int(3),
updated_at_ms: 1706797000000,
updated_by: "robot".to_string(),
},
SettingItem {
key: "robot.mode".to_string(),
value: Value::Enum("autonomous".to_string()),
updated_at_ms: 1706796000000,
updated_by: "operator".to_string(),
},
],
not_found: vec!["nonexistent.key".to_string(), "other.missing".to_string()],
};
let serialized = serialize_get_settings_response(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_settings_response(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_get_settings_response_empty_roundtrip() {
let original = GetSettingsResponse {
settings: vec![],
not_found: vec![],
};
let serialized = serialize_get_settings_response(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_settings_response(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
#[test]
fn test_get_settings_response_no_not_found_roundtrip() {
let original = GetSettingsResponse {
settings: vec![SettingItem {
key: "test.setting".to_string(),
value: Value::String("test_value".to_string()),
updated_at_ms: 1706800000000,
updated_by: "test".to_string(),
}],
not_found: vec![],
};
let serialized = serialize_get_settings_response(&original).expect("Failed to serialize");
let deserialized =
deserialize_get_settings_response(&serialized).expect("Failed to deserialize");
assert_eq!(original, deserialized);
}
}