1use super::types::{
20 FieldDescriptor, FieldType, FieldValue, MessageDescriptor, SchemaRegistryError,
21 SchemaRegistryResult,
22};
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28#[non_exhaustive]
29pub enum WireType {
30 Varint,
32 Fixed64,
34 LengthDelimited,
36 Fixed32,
38}
39
40impl WireType {
41 pub fn id(self) -> u32 {
43 match self {
44 WireType::Varint => 0,
45 WireType::Fixed64 => 1,
46 WireType::LengthDelimited => 2,
47 WireType::Fixed32 => 5,
48 }
49 }
50
51 pub fn from_id(id: u32) -> SchemaRegistryResult<Self> {
53 match id {
54 0 => Ok(WireType::Varint),
55 1 => Ok(WireType::Fixed64),
56 2 => Ok(WireType::LengthDelimited),
57 5 => Ok(WireType::Fixed32),
58 _ => Err(SchemaRegistryError::WireFormat(format!(
59 "unknown wire type id: {id}"
60 ))),
61 }
62 }
63
64 pub fn for_field_type(ft: &FieldType) -> Self {
66 match ft {
67 FieldType::Int32
68 | FieldType::Int64
69 | FieldType::UInt32
70 | FieldType::UInt64
71 | FieldType::Bool => WireType::Varint,
72 FieldType::Float => WireType::Fixed32,
73 FieldType::Double => WireType::Fixed64,
74 FieldType::String
75 | FieldType::Bytes
76 | FieldType::Message(_)
77 | FieldType::Repeated(_) => WireType::LengthDelimited,
78 }
79 }
80}
81
82#[derive(Debug, Clone, PartialEq)]
86#[non_exhaustive]
87pub enum WireValue {
88 Varint(u64),
90 Fixed64([u8; 8]),
92 LengthDelimited(Vec<u8>),
94 Fixed32([u8; 4]),
96}
97
98pub fn encode_varint(value: u64, buf: &mut Vec<u8>) {
103 let mut v = value;
104 loop {
105 let byte = (v & 0x7f) as u8;
106 v >>= 7;
107 if v == 0 {
108 buf.push(byte);
109 break;
110 }
111 buf.push(byte | 0x80);
112 }
113}
114
115pub fn decode_varint(buf: &[u8], pos: &mut usize) -> Option<u64> {
119 let mut result: u64 = 0;
120 let mut shift: u32 = 0;
121 loop {
122 if *pos >= buf.len() || shift >= 64 {
123 return None;
124 }
125 let byte = buf[*pos];
126 *pos += 1;
127 result |= ((byte & 0x7f) as u64) << shift;
128 shift += 7;
129 if byte & 0x80 == 0 {
130 return Some(result);
131 }
132 }
133}
134
135pub fn encode_field(field_number: u32, wire_type: WireType, buf: &mut Vec<u8>) {
139 let tag: u64 = ((field_number as u64) << 3) | (wire_type.id() as u64);
140 encode_varint(tag, buf);
141}
142
143#[derive(Debug, Default)]
163pub struct ProtoEncoder {
164 buf: Vec<u8>,
165}
166
167impl ProtoEncoder {
168 pub fn new() -> Self {
170 Self { buf: Vec::new() }
171 }
172
173 pub fn int32(mut self, field_number: u32, value: i32) -> Self {
175 encode_field(field_number, WireType::Varint, &mut self.buf);
176 encode_varint(value as u64, &mut self.buf);
177 self
178 }
179
180 pub fn int64(mut self, field_number: u32, value: i64) -> Self {
182 encode_field(field_number, WireType::Varint, &mut self.buf);
183 encode_varint(value as u64, &mut self.buf);
184 self
185 }
186
187 pub fn uint32(mut self, field_number: u32, value: u32) -> Self {
189 encode_field(field_number, WireType::Varint, &mut self.buf);
190 encode_varint(value as u64, &mut self.buf);
191 self
192 }
193
194 pub fn uint64(mut self, field_number: u32, value: u64) -> Self {
196 encode_field(field_number, WireType::Varint, &mut self.buf);
197 encode_varint(value, &mut self.buf);
198 self
199 }
200
201 pub fn bool(mut self, field_number: u32, value: bool) -> Self {
203 encode_field(field_number, WireType::Varint, &mut self.buf);
204 encode_varint(value as u64, &mut self.buf);
205 self
206 }
207
208 pub fn float(mut self, field_number: u32, value: f32) -> Self {
210 encode_field(field_number, WireType::Fixed32, &mut self.buf);
211 self.buf.extend_from_slice(&value.to_le_bytes());
212 self
213 }
214
215 pub fn double(mut self, field_number: u32, value: f64) -> Self {
217 encode_field(field_number, WireType::Fixed64, &mut self.buf);
218 self.buf.extend_from_slice(&value.to_le_bytes());
219 self
220 }
221
222 pub fn string(mut self, field_number: u32, value: &str) -> Self {
224 self.write_length_delimited(field_number, value.as_bytes());
225 self
226 }
227
228 pub fn bytes(mut self, field_number: u32, value: &[u8]) -> Self {
230 self.write_length_delimited(field_number, value);
231 self
232 }
233
234 pub fn message(mut self, field_number: u32, nested_bytes: &[u8]) -> Self {
236 self.write_length_delimited(field_number, nested_bytes);
237 self
238 }
239
240 pub fn build(self) -> Vec<u8> {
242 self.buf
243 }
244
245 fn write_length_delimited(&mut self, field_number: u32, data: &[u8]) {
248 encode_field(field_number, WireType::LengthDelimited, &mut self.buf);
249 encode_varint(data.len() as u64, &mut self.buf);
250 self.buf.extend_from_slice(data);
251 }
252}
253
254pub struct ProtoDecoder<'a> {
261 buf: &'a [u8],
262 pos: usize,
263}
264
265impl<'a> ProtoDecoder<'a> {
266 pub fn new(buf: &'a [u8]) -> Self {
268 Self { buf, pos: 0 }
269 }
270
271 pub fn is_empty(&self) -> bool {
273 self.pos >= self.buf.len()
274 }
275
276 pub fn next_field(&mut self) -> Option<SchemaRegistryResult<(u32, WireValue)>> {
281 if self.is_empty() {
282 return None;
283 }
284
285 let tag = decode_varint(self.buf, &mut self.pos)?;
287 let wire_type_id = (tag & 0x07) as u32;
288 let field_number = (tag >> 3) as u32;
289
290 let wire_type = match WireType::from_id(wire_type_id) {
291 Ok(wt) => wt,
292 Err(e) => return Some(Err(e)),
293 };
294
295 let value = match self.decode_payload(wire_type) {
296 Ok(v) => v,
297 Err(e) => return Some(Err(e)),
298 };
299
300 Some(Ok((field_number, value)))
301 }
302
303 pub fn collect_all(&mut self) -> SchemaRegistryResult<Vec<(u32, WireValue)>> {
305 let mut out = Vec::new();
306 while let Some(result) = self.next_field() {
307 out.push(result?);
308 }
309 Ok(out)
310 }
311
312 fn decode_payload(&mut self, wire_type: WireType) -> SchemaRegistryResult<WireValue> {
315 match wire_type {
316 WireType::Varint => {
317 let v = decode_varint(self.buf, &mut self.pos).ok_or_else(|| {
318 SchemaRegistryError::WireFormat("truncated varint".to_string())
319 })?;
320 Ok(WireValue::Varint(v))
321 }
322 WireType::Fixed64 => {
323 if self.pos + 8 > self.buf.len() {
324 return Err(SchemaRegistryError::WireFormat(
325 "truncated fixed64 field".to_string(),
326 ));
327 }
328 let mut b = [0u8; 8];
329 b.copy_from_slice(&self.buf[self.pos..self.pos + 8]);
330 self.pos += 8;
331 Ok(WireValue::Fixed64(b))
332 }
333 WireType::LengthDelimited => {
334 let len = decode_varint(self.buf, &mut self.pos).ok_or_else(|| {
335 SchemaRegistryError::WireFormat(
336 "truncated length prefix in length-delimited field".to_string(),
337 )
338 })? as usize;
339
340 if self.pos + len > self.buf.len() {
341 return Err(SchemaRegistryError::WireFormat(format!(
342 "length-delimited field claims {len} bytes but only {} remain",
343 self.buf.len() - self.pos
344 )));
345 }
346 let payload = self.buf[self.pos..self.pos + len].to_vec();
347 self.pos += len;
348 Ok(WireValue::LengthDelimited(payload))
349 }
350 WireType::Fixed32 => {
351 if self.pos + 4 > self.buf.len() {
352 return Err(SchemaRegistryError::WireFormat(
353 "truncated fixed32 field".to_string(),
354 ));
355 }
356 let mut b = [0u8; 4];
357 b.copy_from_slice(&self.buf[self.pos..self.pos + 4]);
358 self.pos += 4;
359 Ok(WireValue::Fixed32(b))
360 }
361 }
362 }
363}
364
365pub fn encode_message(schema: &MessageDescriptor, values: &[(u32, FieldValue)]) -> Vec<u8> {
373 let mut buf = Vec::new();
374
375 for (field_number, value) in values {
376 let field_desc = match schema.field_by_number(*field_number) {
378 Some(fd) => fd,
379 None => continue,
380 };
381
382 encode_field_value(*field_number, &field_desc.field_type, value, &mut buf);
383 }
384
385 buf
386}
387
388pub fn decode_message(
394 schema: &MessageDescriptor,
395 bytes: &[u8],
396) -> SchemaRegistryResult<Vec<(std::string::String, FieldValue)>> {
397 let mut decoder = ProtoDecoder::new(bytes);
398 let raw_fields = decoder.collect_all()?;
399 let mut out = Vec::new();
400
401 for (field_number, wire_value) in raw_fields {
402 let field_desc = match schema.field_by_number(field_number) {
403 Some(fd) => fd,
404 None => continue, };
406
407 let field_value = wire_value_to_field_value(&field_desc.field_type, wire_value)?;
408 out.push((field_desc.name.clone(), field_value));
409 }
410
411 Ok(out)
412}
413
414fn encode_field_value(
417 field_number: u32,
418 field_type: &FieldType,
419 value: &FieldValue,
420 buf: &mut Vec<u8>,
421) {
422 match (field_type, value) {
423 (FieldType::Int32, FieldValue::Int32(v)) => {
424 encode_field(field_number, WireType::Varint, buf);
425 encode_varint(*v as u64, buf);
426 }
427 (FieldType::Int64, FieldValue::Int64(v)) => {
428 encode_field(field_number, WireType::Varint, buf);
429 encode_varint(*v as u64, buf);
430 }
431 (FieldType::Int64, FieldValue::Int32(v)) => {
432 encode_field(field_number, WireType::Varint, buf);
434 encode_varint(*v as u64, buf);
435 }
436 (FieldType::UInt32, FieldValue::UInt32(v)) => {
437 encode_field(field_number, WireType::Varint, buf);
438 encode_varint(*v as u64, buf);
439 }
440 (FieldType::UInt64, FieldValue::UInt64(v)) => {
441 encode_field(field_number, WireType::Varint, buf);
442 encode_varint(*v, buf);
443 }
444 (FieldType::UInt64, FieldValue::UInt32(v)) => {
445 encode_field(field_number, WireType::Varint, buf);
446 encode_varint(*v as u64, buf);
447 }
448 (FieldType::Bool, FieldValue::Bool(v)) => {
449 encode_field(field_number, WireType::Varint, buf);
450 encode_varint(*v as u64, buf);
451 }
452 (FieldType::Float, FieldValue::Float(v)) => {
453 encode_field(field_number, WireType::Fixed32, buf);
454 buf.extend_from_slice(&v.to_le_bytes());
455 }
456 (FieldType::Double, FieldValue::Double(v)) => {
457 encode_field(field_number, WireType::Fixed64, buf);
458 buf.extend_from_slice(&v.to_le_bytes());
459 }
460 (FieldType::Double, FieldValue::Float(v)) => {
461 encode_field(field_number, WireType::Fixed64, buf);
462 buf.extend_from_slice(&(*v as f64).to_le_bytes());
463 }
464 (FieldType::String, FieldValue::Str(s)) => {
465 let data = s.as_bytes();
466 encode_field(field_number, WireType::LengthDelimited, buf);
467 encode_varint(data.len() as u64, buf);
468 buf.extend_from_slice(data);
469 }
470 (FieldType::Bytes, FieldValue::Bytes(data)) => {
471 encode_field(field_number, WireType::LengthDelimited, buf);
472 encode_varint(data.len() as u64, buf);
473 buf.extend_from_slice(data);
474 }
475 (FieldType::Message(_), FieldValue::Message(data)) => {
476 encode_field(field_number, WireType::LengthDelimited, buf);
477 encode_varint(data.len() as u64, buf);
478 buf.extend_from_slice(data);
479 }
480 (FieldType::Repeated(_), FieldValue::Bytes(data)) => {
481 encode_field(field_number, WireType::LengthDelimited, buf);
483 encode_varint(data.len() as u64, buf);
484 buf.extend_from_slice(data);
485 }
486 _ => {
487 }
489 }
490}
491
492fn wire_value_to_field_value(ft: &FieldType, wv: WireValue) -> SchemaRegistryResult<FieldValue> {
493 match (ft, wv) {
494 (FieldType::Int32, WireValue::Varint(v)) => Ok(FieldValue::Int32(v as i32)),
495 (FieldType::Int64, WireValue::Varint(v)) => Ok(FieldValue::Int64(v as i64)),
496 (FieldType::UInt32, WireValue::Varint(v)) => Ok(FieldValue::UInt32(v as u32)),
497 (FieldType::UInt64, WireValue::Varint(v)) => Ok(FieldValue::UInt64(v)),
498 (FieldType::Bool, WireValue::Varint(v)) => Ok(FieldValue::Bool(v != 0)),
499 (FieldType::Float, WireValue::Fixed32(b)) => Ok(FieldValue::Float(f32::from_le_bytes(b))),
500 (FieldType::Double, WireValue::Fixed64(b)) => Ok(FieldValue::Double(f64::from_le_bytes(b))),
501 (FieldType::String, WireValue::LengthDelimited(data)) => {
502 let s = std::string::String::from_utf8(data).map_err(|e| {
503 SchemaRegistryError::WireFormat(format!("invalid UTF-8 in string field: {e}"))
504 })?;
505 Ok(FieldValue::Str(s))
506 }
507 (FieldType::Bytes, WireValue::LengthDelimited(data)) => Ok(FieldValue::Bytes(data)),
508 (FieldType::Message(_), WireValue::LengthDelimited(data)) => Ok(FieldValue::Message(data)),
509 (FieldType::Repeated(_), WireValue::LengthDelimited(data)) => Ok(FieldValue::Bytes(data)),
510 (ft, wv) => Err(SchemaRegistryError::WireFormat(format!(
511 "wire type mismatch for field type {}: got {:?}",
512 ft.proto_name(),
513 wv
514 ))),
515 }
516}
517
518#[cfg(test)]
521mod tests {
522 use super::*;
523
524 #[test]
527 fn test_varint_zero() {
528 let mut buf = Vec::new();
529 encode_varint(0, &mut buf);
530 assert_eq!(buf, [0x00]);
531 let mut pos = 0;
532 assert_eq!(decode_varint(&buf, &mut pos), Some(0));
533 assert_eq!(pos, 1);
534 }
535
536 #[test]
537 fn test_varint_one_byte_boundary() {
538 let mut buf = Vec::new();
539 encode_varint(127, &mut buf);
540 assert_eq!(buf, [0x7f]);
541 }
542
543 #[test]
544 fn test_varint_two_byte_boundary() {
545 let mut buf = Vec::new();
546 encode_varint(128, &mut buf);
547 assert_eq!(buf, [0x80, 0x01]);
548 }
549
550 #[test]
551 fn test_varint_300() {
552 let mut buf = Vec::new();
553 encode_varint(300, &mut buf);
554 assert_eq!(buf, [0xac, 0x02]);
555 let mut pos = 0;
556 assert_eq!(decode_varint(&buf, &mut pos), Some(300));
557 }
558
559 #[test]
560 fn test_varint_u64_max() {
561 let mut buf = Vec::new();
562 encode_varint(u64::MAX, &mut buf);
563 assert_eq!(buf.len(), 10);
564 let mut pos = 0;
565 assert_eq!(decode_varint(&buf, &mut pos), Some(u64::MAX));
566 }
567
568 #[test]
569 fn test_varint_roundtrip_sequence() {
570 let values: &[u64] = &[0, 1, 127, 128, 255, 1024, 65535, 1 << 32, u64::MAX];
571 for &v in values {
572 let mut buf = Vec::new();
573 encode_varint(v, &mut buf);
574 let mut pos = 0;
575 assert_eq!(decode_varint(&buf, &mut pos), Some(v), "value={v}");
576 }
577 }
578
579 #[test]
580 fn test_decode_varint_truncated_returns_none() {
581 let buf = [0x80]; let mut pos = 0;
584 assert_eq!(decode_varint(&buf, &mut pos), None);
585 }
586
587 #[test]
590 fn test_wire_type_tag_field_1_varint() {
591 let mut buf = Vec::new();
593 encode_field(1, WireType::Varint, &mut buf);
594 assert_eq!(buf, [0x08]);
595 }
596
597 #[test]
598 fn test_wire_type_tag_field_2_len_delim() {
599 let mut buf = Vec::new();
601 encode_field(2, WireType::LengthDelimited, &mut buf);
602 assert_eq!(buf, [0x12]);
603 }
604
605 #[test]
608 fn test_proto_encoder_int32() {
609 let bytes = ProtoEncoder::new().int32(1, 150).build();
610 assert_eq!(bytes, [0x08, 0x96, 0x01]);
612 }
613
614 #[test]
615 fn test_proto_encoder_string() {
616 let bytes = ProtoEncoder::new().string(1, "testing").build();
617 assert_eq!(bytes[0], 0x0a);
619 assert_eq!(bytes[1], 7);
620 assert_eq!(&bytes[2..], b"testing");
621 }
622
623 #[test]
624 fn test_proto_encoder_bool_true() {
625 let bytes = ProtoEncoder::new().bool(1, true).build();
626 assert_eq!(bytes, [0x08, 0x01]);
627 }
628
629 #[test]
630 fn test_proto_encoder_bool_false() {
631 let bytes = ProtoEncoder::new().bool(1, false).build();
632 assert_eq!(bytes, [0x08, 0x00]);
633 }
634
635 #[test]
636 fn test_proto_encoder_float() {
637 let v = 1.0_f32;
638 let bytes = ProtoEncoder::new().float(1, v).build();
639 assert_eq!(bytes[0], 0x0d);
641 let decoded = f32::from_le_bytes(bytes[1..5].try_into().expect("slice"));
642 assert!((decoded - 1.0).abs() < 1e-6);
643 }
644
645 #[test]
646 fn test_proto_encoder_double() {
647 let v = std::f64::consts::PI;
648 let bytes = ProtoEncoder::new().double(1, v).build();
649 assert_eq!(bytes[0], 0x09);
651 let decoded = f64::from_le_bytes(bytes[1..9].try_into().expect("slice"));
652 assert!((decoded - std::f64::consts::PI).abs() < 1e-12);
653 }
654
655 #[test]
656 fn test_proto_encoder_bytes() {
657 let data = b"\xde\xad\xbe\xef";
658 let bytes = ProtoEncoder::new().bytes(1, data).build();
659 assert_eq!(bytes[0], 0x0a); assert_eq!(bytes[1], 4); assert_eq!(&bytes[2..], data);
662 }
663
664 #[test]
665 fn test_proto_encoder_message_nested() {
666 let inner = ProtoEncoder::new().int32(1, 42).build();
667 let outer = ProtoEncoder::new().message(1, &inner).build();
668 let mut dec = ProtoDecoder::new(&outer);
670 let (fn_, wv) = dec.next_field().expect("field").expect("ok");
671 assert_eq!(fn_, 1);
672 if let WireValue::LengthDelimited(payload) = wv {
673 assert_eq!(payload, inner);
674 } else {
675 panic!("expected LengthDelimited");
676 }
677 }
678
679 #[test]
682 fn test_proto_decoder_varint_field() {
683 let bytes = ProtoEncoder::new().int64(3, 9999).build();
684 let mut dec = ProtoDecoder::new(&bytes);
685 let (fn_, wv) = dec.next_field().expect("field").expect("ok");
686 assert_eq!(fn_, 3);
687 assert_eq!(wv, WireValue::Varint(9999));
688 assert!(dec.is_empty());
689 }
690
691 #[test]
692 fn test_proto_decoder_multiple_fields() {
693 let bytes = ProtoEncoder::new()
694 .int32(1, 1)
695 .string(2, "abc")
696 .bool(3, true)
697 .build();
698
699 let mut dec = ProtoDecoder::new(&bytes);
700 let fields = dec.collect_all().expect("ok");
701 assert_eq!(fields.len(), 3);
702 assert_eq!(fields[0].0, 1);
703 assert_eq!(fields[1].0, 2);
704 assert_eq!(fields[2].0, 3);
705 }
706
707 #[test]
710 fn test_encode_decode_all_field_types() {
711 use crate::schema_registry::types::FieldDescriptor;
712
713 let desc = MessageDescriptor::new("AllTypes", "test")
714 .with_field(FieldDescriptor::optional(1, "i32", FieldType::Int32))
715 .with_field(FieldDescriptor::optional(2, "i64", FieldType::Int64))
716 .with_field(FieldDescriptor::optional(3, "u32", FieldType::UInt32))
717 .with_field(FieldDescriptor::optional(4, "u64", FieldType::UInt64))
718 .with_field(FieldDescriptor::optional(5, "flt", FieldType::Float))
719 .with_field(FieldDescriptor::optional(6, "dbl", FieldType::Double))
720 .with_field(FieldDescriptor::optional(7, "b", FieldType::Bool))
721 .with_field(FieldDescriptor::optional(8, "s", FieldType::String))
722 .with_field(FieldDescriptor::optional(9, "raw", FieldType::Bytes));
723
724 let values: Vec<(u32, FieldValue)> = vec![
725 (1, FieldValue::Int32(-7)),
726 (2, FieldValue::Int64(-9_999_999_999)),
727 (3, FieldValue::UInt32(42)),
728 (4, FieldValue::UInt64(u64::MAX)),
729 (5, FieldValue::Float(3.25)),
730 (6, FieldValue::Double(2.345_678_901)),
731 (7, FieldValue::Bool(true)),
732 (8, FieldValue::Str("hello".to_string())),
733 (9, FieldValue::Bytes(vec![0xca, 0xfe])),
734 ];
735
736 let bytes = encode_message(&desc, &values);
737 let decoded = decode_message(&desc, &bytes).expect("decode ok");
738 assert_eq!(decoded.len(), 9);
739
740 assert_eq!(decoded[0], ("i32".to_string(), FieldValue::Int32(-7)));
741 assert_eq!(
742 decoded[1],
743 ("i64".to_string(), FieldValue::Int64(-9_999_999_999))
744 );
745 assert_eq!(decoded[2], ("u32".to_string(), FieldValue::UInt32(42)));
746 assert_eq!(
747 decoded[3],
748 ("u64".to_string(), FieldValue::UInt64(u64::MAX))
749 );
750 assert_eq!(decoded[6], ("b".to_string(), FieldValue::Bool(true)));
751 assert_eq!(
752 decoded[7],
753 ("s".to_string(), FieldValue::Str("hello".to_string()))
754 );
755 assert_eq!(
756 decoded[8],
757 ("raw".to_string(), FieldValue::Bytes(vec![0xca, 0xfe]))
758 );
759 }
760
761 #[test]
762 fn test_message_encode_decode_roundtrip() {
763 use crate::schema_registry::types::FieldDescriptor;
764
765 let desc = MessageDescriptor::new("Point", "geometry")
766 .with_field(FieldDescriptor::optional(1, "x", FieldType::Double))
767 .with_field(FieldDescriptor::optional(2, "y", FieldType::Double))
768 .with_field(FieldDescriptor::optional(3, "label", FieldType::String));
769
770 let values = vec![
771 (1, FieldValue::Double(1.5)),
772 (2, FieldValue::Double(-3.75)),
773 (3, FieldValue::Str("origin".to_string())),
774 ];
775
776 let encoded = encode_message(&desc, &values);
777 let decoded = decode_message(&desc, &encoded).expect("decode ok");
778
779 assert_eq!(decoded.len(), 3);
780 assert_eq!(decoded[2].1, FieldValue::Str("origin".to_string()));
781 }
782
783 #[test]
784 fn test_nested_message_encoding() {
785 use crate::schema_registry::types::FieldDescriptor;
786
787 let inner_desc = MessageDescriptor::new("Inner", "test")
789 .with_field(FieldDescriptor::optional(1, "id", FieldType::Int32));
790
791 let inner_bytes = encode_message(&inner_desc, &[(1, FieldValue::Int32(99))]);
792
793 let outer_desc = MessageDescriptor::new("Outer", "test").with_field(
795 FieldDescriptor::optional(1, "nested", FieldType::Message("Inner".to_string())),
796 );
797
798 let outer_values = vec![(1, FieldValue::Message(inner_bytes.clone()))];
799 let outer_bytes = encode_message(&outer_desc, &outer_values);
800 let outer_decoded = decode_message(&outer_desc, &outer_bytes).expect("ok");
801
802 assert_eq!(outer_decoded.len(), 1);
803 if let FieldValue::Message(payload) = &outer_decoded[0].1 {
804 assert_eq!(payload, &inner_bytes);
805 } else {
806 panic!("expected Message variant");
807 }
808 }
809
810 #[test]
811 fn test_repeated_field_encoding() {
812 use crate::schema_registry::types::FieldDescriptor;
813
814 let desc = MessageDescriptor::new("Bag", "test").with_field(FieldDescriptor::optional(
816 1,
817 "items",
818 FieldType::Repeated(Box::new(FieldType::Int32)),
819 ));
820
821 let mut packed = Vec::new();
823 for v in [1u64, 2, 3] {
824 encode_varint(v, &mut packed);
825 }
826
827 let values = vec![(1, FieldValue::Bytes(packed.clone()))];
828 let bytes = encode_message(&desc, &values);
829 let decoded = decode_message(&desc, &bytes).expect("ok");
830
831 assert_eq!(decoded.len(), 1);
832 assert_eq!(decoded[0].0, "items");
833 if let FieldValue::Bytes(b) = &decoded[0].1 {
834 assert_eq!(b, &packed);
835 } else {
836 panic!("expected Bytes");
837 }
838 }
839
840 #[test]
841 fn test_unknown_field_skipped_on_decode() {
842 use crate::schema_registry::types::FieldDescriptor;
843
844 let desc_full = MessageDescriptor::new("M", "test")
846 .with_field(FieldDescriptor::optional(1, "a", FieldType::Int32))
847 .with_field(FieldDescriptor::optional(2, "b", FieldType::String));
848
849 let bytes = encode_message(
850 &desc_full,
851 &[
852 (1, FieldValue::Int32(7)),
853 (2, FieldValue::Str("x".to_string())),
854 ],
855 );
856
857 let desc_partial = MessageDescriptor::new("M", "test")
859 .with_field(FieldDescriptor::optional(1, "a", FieldType::Int32));
860
861 let decoded = decode_message(&desc_partial, &bytes).expect("ok");
862 assert_eq!(decoded.len(), 1);
864 assert_eq!(decoded[0].1, FieldValue::Int32(7));
865 }
866}