use serde::{Deserialize, Serialize};
use super::text_fields::TextFields;
const DISC_TEXT: u8 = 0x01;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
#[non_exhaustive]
pub enum RequestFields {
Text(TextFields),
}
impl zerompk::ToMessagePack for RequestFields {
fn write<W: zerompk::Write>(&self, writer: &mut W) -> zerompk::Result<()> {
writer.write_array_len(2)?;
match self {
RequestFields::Text(fields) => {
writer.write_u8(DISC_TEXT)?;
fields.write(writer)?;
}
}
Ok(())
}
}
impl<'a> zerompk::FromMessagePack<'a> for RequestFields {
fn read<R: zerompk::Read<'a>>(reader: &mut R) -> zerompk::Result<Self> {
let len = reader.read_array_len()?;
if len != 2 {
return Err(zerompk::Error::ArrayLengthMismatch {
expected: 2,
actual: len,
});
}
let discriminant = reader.read_u8()?;
match discriminant {
DISC_TEXT => {
let fields = TextFields::read(reader)?;
Ok(RequestFields::Text(fields))
}
other => Err(zerompk::Error::InvalidMarker(other)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn requestfields_text_discriminant_roundtrip() {
let rf = RequestFields::Text(TextFields {
sql: Some("SELECT 42".into()),
top_k: Some(5),
..Default::default()
});
let bytes = zerompk::to_msgpack_vec(&rf).expect("encode");
assert_eq!(bytes[0], 0x92, "expected fixarray(2)");
assert_eq!(bytes[1], DISC_TEXT, "expected Text discriminant");
let decoded: RequestFields = zerompk::from_msgpack(&bytes).expect("decode");
match decoded {
RequestFields::Text(tf) => {
assert_eq!(tf.sql.as_deref(), Some("SELECT 42"));
assert_eq!(tf.top_k, Some(5));
}
}
}
#[test]
fn requestfields_unknown_discriminant_rejected() {
let buf = vec![
0x92u8, 0xFF, 0x80, ];
let result: zerompk::Result<RequestFields> = zerompk::from_msgpack(&buf);
assert!(result.is_err(), "expected error for unknown discriminant");
match result.unwrap_err() {
zerompk::Error::InvalidMarker(v) => assert_eq!(v, 0xFF),
e => panic!(
"expected InvalidMarker for unknown discriminant, got: {:?}",
e
),
}
}
}