1use super::error::BinaryError;
8use super::types::TypeTag;
9use super::varint;
10use lnmp_core::{LnmpRecord, LnmpValue};
11
12#[derive(Debug, Clone)]
14pub struct NestedEncoderConfig {
15 pub max_depth: usize,
17 pub max_record_size: Option<usize>,
19 pub validate_canonical: bool,
21}
22
23impl Default for NestedEncoderConfig {
24 fn default() -> Self {
25 Self {
26 max_depth: 32,
27 max_record_size: None,
28 validate_canonical: false,
29 }
30 }
31}
32
33impl NestedEncoderConfig {
34 pub fn new() -> Self {
36 Self::default()
37 }
38
39 pub fn with_max_depth(mut self, max_depth: usize) -> Self {
41 self.max_depth = max_depth;
42 self
43 }
44
45 pub fn with_max_record_size(mut self, max_size: Option<usize>) -> Self {
47 self.max_record_size = max_size;
48 self
49 }
50
51 pub fn with_validate_canonical(mut self, validate: bool) -> Self {
53 self.validate_canonical = validate;
54 self
55 }
56}
57
58#[derive(Debug)]
62pub struct BinaryNestedEncoder {
63 config: NestedEncoderConfig,
64}
65
66impl BinaryNestedEncoder {
67 pub fn new() -> Self {
69 Self {
70 config: NestedEncoderConfig::default(),
71 }
72 }
73
74 pub fn with_config(config: NestedEncoderConfig) -> Self {
76 Self { config }
77 }
78
79 pub fn encode_nested_record(&self, record: &LnmpRecord) -> Result<Vec<u8>, BinaryError> {
104 self.encode_nested_record_with_depth(record, 0)
105 }
106
107 fn encode_nested_record_with_depth(
109 &self,
110 record: &LnmpRecord,
111 current_depth: usize,
112 ) -> Result<Vec<u8>, BinaryError> {
113 if current_depth >= self.config.max_depth {
115 return Err(BinaryError::NestingDepthExceeded {
116 depth: current_depth,
117 max: self.config.max_depth,
118 });
119 }
120
121 let mut buffer = Vec::new();
122
123 buffer.push(TypeTag::NestedRecord.to_u8());
125
126 let fields = record.sorted_fields();
128
129 let field_count = fields.len() as i64;
131 buffer.extend_from_slice(&varint::encode(field_count));
132
133 for field in fields {
135 buffer.extend_from_slice(&varint::encode(field.fid as i64));
137
138 let value_bytes = self.encode_value_recursive(&field.value, current_depth + 1)?;
140 buffer.extend_from_slice(&value_bytes);
141
142 if let Some(max_size) = self.config.max_record_size {
144 if buffer.len() > max_size {
145 return Err(BinaryError::RecordSizeExceeded {
146 size: buffer.len(),
147 max: max_size,
148 });
149 }
150 }
151 }
152
153 Ok(buffer)
154 }
155
156 pub fn encode_nested_array(&self, records: &[LnmpRecord]) -> Result<Vec<u8>, BinaryError> {
181 self.encode_nested_array_with_depth(records, 0)
182 }
183
184 fn encode_nested_array_with_depth(
186 &self,
187 records: &[LnmpRecord],
188 current_depth: usize,
189 ) -> Result<Vec<u8>, BinaryError> {
190 if current_depth >= self.config.max_depth {
192 return Err(BinaryError::NestingDepthExceeded {
193 depth: current_depth,
194 max: self.config.max_depth,
195 });
196 }
197
198 let mut buffer = Vec::new();
199
200 buffer.push(TypeTag::NestedArray.to_u8());
202
203 let element_count = records.len() as i64;
205 buffer.extend_from_slice(&varint::encode(element_count));
206
207 for record in records {
209 let record_bytes = self.encode_nested_record_with_depth(record, current_depth + 1)?;
211 buffer.extend_from_slice(&record_bytes);
212
213 if let Some(max_size) = self.config.max_record_size {
215 if buffer.len() > max_size {
216 return Err(BinaryError::RecordSizeExceeded {
217 size: buffer.len(),
218 max: max_size,
219 });
220 }
221 }
222 }
223
224 Ok(buffer)
225 }
226
227 fn encode_value_recursive(
229 &self,
230 value: &LnmpValue,
231 current_depth: usize,
232 ) -> Result<Vec<u8>, BinaryError> {
233 if current_depth >= self.config.max_depth
235 && matches!(
236 value,
237 LnmpValue::NestedRecord(_) | LnmpValue::NestedArray(_)
238 )
239 {
240 return Err(BinaryError::NestingDepthExceeded {
241 depth: current_depth,
242 max: self.config.max_depth,
243 });
244 }
245
246 match value {
247 LnmpValue::Int(i) => {
248 let mut buffer = Vec::new();
249 buffer.push(TypeTag::Int.to_u8());
250 buffer.extend_from_slice(&varint::encode(*i));
251 Ok(buffer)
252 }
253 LnmpValue::Float(f) => {
254 let mut buffer = Vec::new();
255 buffer.push(TypeTag::Float.to_u8());
256 buffer.extend_from_slice(&f.to_le_bytes());
257 Ok(buffer)
258 }
259 LnmpValue::Bool(b) => {
260 let mut buffer = Vec::new();
261 buffer.push(TypeTag::Bool.to_u8());
262 buffer.push(if *b { 0x01 } else { 0x00 });
263 Ok(buffer)
264 }
265 LnmpValue::String(s) => {
266 let mut buffer = Vec::new();
267 buffer.push(TypeTag::String.to_u8());
268 let bytes = s.as_bytes();
269 buffer.extend_from_slice(&varint::encode(bytes.len() as i64));
270 buffer.extend_from_slice(bytes);
271 Ok(buffer)
272 }
273 LnmpValue::StringArray(arr) => {
274 let mut buffer = Vec::new();
275 buffer.push(TypeTag::StringArray.to_u8());
276 buffer.extend_from_slice(&varint::encode(arr.len() as i64));
277 for s in arr {
278 let bytes = s.as_bytes();
279 buffer.extend_from_slice(&varint::encode(bytes.len() as i64));
280 buffer.extend_from_slice(bytes);
281 }
282 Ok(buffer)
283 }
284 LnmpValue::EmbeddingDelta(delta) => {
285 let mut buffer = Vec::new();
286 buffer.push(TypeTag::Embedding.to_u8()); let delta_bytes = delta.encode().map_err(|_| BinaryError::InvalidValue {
289 field_id: 0,
290 type_tag: TypeTag::Embedding.to_u8(),
291 reason: "Failed to encode delta".to_string(),
292 })?;
293 buffer.extend_from_slice(&(delta_bytes.len() as u32).to_le_bytes());
294 buffer.extend_from_slice(&delta_bytes);
295 Ok(buffer)
296 }
297 LnmpValue::Embedding(vec) => {
298 let encoded = lnmp_embedding::Encoder::encode(vec).map_err(|_| {
300 BinaryError::InvalidValue {
301 field_id: 0,
302 type_tag: TypeTag::Embedding.to_u8(),
303 reason: "Failed to encode embedding".to_string(),
304 }
305 })?;
306
307 let mut buffer = Vec::new();
308 buffer.push(TypeTag::Embedding.to_u8());
309 buffer.extend_from_slice(&varint::encode(encoded.len() as i64));
310 buffer.extend_from_slice(&encoded);
311 Ok(buffer)
312 }
313 LnmpValue::QuantizedEmbedding(qv) => {
314 let mut buffer = Vec::new();
316 buffer.push(TypeTag::QuantizedEmbedding.to_u8()); buffer.push(qv.scheme as u8);
320
321 buffer.extend_from_slice(&qv.scale.to_le_bytes());
323
324 buffer.push(qv.zero_point as u8);
326
327 buffer.extend_from_slice(&qv.min_val.to_le_bytes());
329
330 buffer.extend_from_slice(&qv.dim.to_le_bytes());
332
333 buffer.extend_from_slice(&varint::encode(qv.data.len() as i64));
335 buffer.extend_from_slice(&qv.data);
336
337 Ok(buffer)
338 }
339 LnmpValue::NestedRecord(record) => {
340 self.encode_nested_record_with_depth(record, current_depth)
341 }
342 LnmpValue::NestedArray(records) => {
343 self.encode_nested_array_with_depth(records, current_depth)
344 }
345 }
346 }
347}
348
349impl Default for BinaryNestedEncoder {
350 fn default() -> Self {
351 Self::new()
352 }
353}
354
355#[cfg(test)]
356mod tests {
357 #![allow(clippy::approx_constant)]
358
359 use super::*;
360 use lnmp_core::LnmpField;
361
362 #[test]
363 fn test_nested_encoder_config_default() {
364 let config = NestedEncoderConfig::default();
365 assert_eq!(config.max_depth, 32);
366 assert_eq!(config.max_record_size, None);
367 assert!(!config.validate_canonical);
368 }
369
370 #[test]
371 fn test_nested_encoder_config_builder() {
372 let config = NestedEncoderConfig::new()
373 .with_max_depth(16)
374 .with_max_record_size(Some(1024))
375 .with_validate_canonical(true);
376
377 assert_eq!(config.max_depth, 16);
378 assert_eq!(config.max_record_size, Some(1024));
379 assert!(config.validate_canonical);
380 }
381
382 #[test]
383 fn test_encode_empty_nested_record() {
384 let encoder = BinaryNestedEncoder::new();
385 let record = LnmpRecord::new();
386
387 let result = encoder.encode_nested_record(&record).unwrap();
388
389 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x00); assert_eq!(result.len(), 2);
393 }
394
395 #[test]
396 fn test_encode_single_level_nested_record() {
397 let encoder = BinaryNestedEncoder::new();
398 let mut record = LnmpRecord::new();
399 record.add_field(LnmpField {
400 fid: 1,
401 value: LnmpValue::Int(42),
402 });
403 record.add_field(LnmpField {
404 fid: 2,
405 value: LnmpValue::String("test".to_string()),
406 });
407
408 let result = encoder.encode_nested_record(&record).unwrap();
409
410 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x02); }
414
415 #[test]
416 fn test_encode_nested_record_canonical_ordering() {
417 let encoder = BinaryNestedEncoder::new();
418 let mut record = LnmpRecord::new();
419 record.add_field(LnmpField {
421 fid: 10,
422 value: LnmpValue::Int(3),
423 });
424 record.add_field(LnmpField {
425 fid: 2,
426 value: LnmpValue::Int(1),
427 });
428 record.add_field(LnmpField {
429 fid: 5,
430 value: LnmpValue::Int(2),
431 });
432
433 let result = encoder.encode_nested_record(&record).unwrap();
434
435 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x03); assert_eq!(result[2], 0x02); }
443
444 #[test]
445 fn test_encode_empty_nested_array() {
446 let encoder = BinaryNestedEncoder::new();
447 let records: Vec<LnmpRecord> = vec![];
448
449 let result = encoder.encode_nested_array(&records).unwrap();
450
451 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x00); assert_eq!(result.len(), 2);
455 }
456
457 #[test]
458 fn test_encode_nested_array_single_record() {
459 let encoder = BinaryNestedEncoder::new();
460 let mut record = LnmpRecord::new();
461 record.add_field(LnmpField {
462 fid: 1,
463 value: LnmpValue::Int(42),
464 });
465
466 let result = encoder.encode_nested_array(&[record]).unwrap();
467
468 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x01); assert_eq!(result[2], 0x06); }
474
475 #[test]
476 fn test_encode_nested_array_multiple_records() {
477 let encoder = BinaryNestedEncoder::new();
478 let mut record1 = LnmpRecord::new();
479 record1.add_field(LnmpField {
480 fid: 1,
481 value: LnmpValue::Int(1),
482 });
483
484 let mut record2 = LnmpRecord::new();
485 record2.add_field(LnmpField {
486 fid: 1,
487 value: LnmpValue::Int(2),
488 });
489
490 let result = encoder.encode_nested_array(&[record1, record2]).unwrap();
491
492 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x02); }
496
497 #[test]
498 fn test_encode_depth_limit_exceeded() {
499 let config = NestedEncoderConfig::new().with_max_depth(2);
500 let encoder = BinaryNestedEncoder::with_config(config);
501
502 let mut level3 = LnmpRecord::new();
504 level3.add_field(LnmpField {
505 fid: 1,
506 value: LnmpValue::Int(42),
507 });
508
509 let mut level2 = LnmpRecord::new();
510 level2.add_field(LnmpField {
511 fid: 2,
512 value: LnmpValue::NestedRecord(Box::new(level3)),
513 });
514
515 let mut level1 = LnmpRecord::new();
516 level1.add_field(LnmpField {
517 fid: 3,
518 value: LnmpValue::NestedRecord(Box::new(level2)),
519 });
520
521 let result = encoder.encode_nested_record(&level1);
522
523 assert!(result.is_err());
524 match result {
525 Err(BinaryError::NestingDepthExceeded { depth, max }) => {
526 assert_eq!(max, 2);
527 assert!(depth >= 2);
528 }
529 _ => panic!("Expected NestingDepthExceeded error"),
530 }
531 }
532
533 #[test]
534 fn test_encode_size_limit_exceeded() {
535 let config = NestedEncoderConfig::new().with_max_record_size(Some(10));
536 let encoder = BinaryNestedEncoder::with_config(config);
537
538 let mut record = LnmpRecord::new();
539 for i in 0..100 {
541 record.add_field(LnmpField {
542 fid: i,
543 value: LnmpValue::String("test".to_string()),
544 });
545 }
546
547 let result = encoder.encode_nested_record(&record);
548
549 assert!(result.is_err());
550 match result {
551 Err(BinaryError::RecordSizeExceeded { size, max }) => {
552 assert_eq!(max, 10);
553 assert!(size > 10);
554 }
555 _ => panic!("Expected RecordSizeExceeded error"),
556 }
557 }
558
559 #[test]
560 fn test_encode_multi_level_nested_record() {
561 let encoder = BinaryNestedEncoder::new();
562
563 let mut inner_record = LnmpRecord::new();
565 inner_record.add_field(LnmpField {
566 fid: 1,
567 value: LnmpValue::Int(42),
568 });
569
570 let mut outer_record = LnmpRecord::new();
571 outer_record.add_field(LnmpField {
572 fid: 2,
573 value: LnmpValue::NestedRecord(Box::new(inner_record)),
574 });
575
576 let result = encoder.encode_nested_record(&outer_record).unwrap();
577
578 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x01); assert_eq!(result[2], 0x02); assert_eq!(result[3], 0x06); }
586
587 #[test]
588 fn test_encode_nested_record_depth_2() {
589 let encoder = BinaryNestedEncoder::new();
590
591 let mut level2 = LnmpRecord::new();
593 level2.add_field(LnmpField {
594 fid: 1,
595 value: LnmpValue::Int(100),
596 });
597
598 let mut level1 = LnmpRecord::new();
599 level1.add_field(LnmpField {
600 fid: 2,
601 value: LnmpValue::NestedRecord(Box::new(level2)),
602 });
603
604 let result = encoder.encode_nested_record(&level1).unwrap();
605 assert!(!result.is_empty());
606 assert_eq!(result[0], 0x06); }
608
609 #[test]
610 fn test_encode_nested_record_depth_3() {
611 let encoder = BinaryNestedEncoder::new();
612
613 let mut level3 = LnmpRecord::new();
615 level3.add_field(LnmpField {
616 fid: 1,
617 value: LnmpValue::Int(100),
618 });
619
620 let mut level2 = LnmpRecord::new();
621 level2.add_field(LnmpField {
622 fid: 2,
623 value: LnmpValue::NestedRecord(Box::new(level3)),
624 });
625
626 let mut level1 = LnmpRecord::new();
627 level1.add_field(LnmpField {
628 fid: 3,
629 value: LnmpValue::NestedRecord(Box::new(level2)),
630 });
631
632 let result = encoder.encode_nested_record(&level1).unwrap();
633 assert!(!result.is_empty());
634 assert_eq!(result[0], 0x06); }
636
637 #[test]
638 fn test_encode_nested_record_depth_4() {
639 let encoder = BinaryNestedEncoder::new();
640
641 let mut level4 = LnmpRecord::new();
643 level4.add_field(LnmpField {
644 fid: 1,
645 value: LnmpValue::Int(100),
646 });
647
648 let mut level3 = LnmpRecord::new();
649 level3.add_field(LnmpField {
650 fid: 2,
651 value: LnmpValue::NestedRecord(Box::new(level4)),
652 });
653
654 let mut level2 = LnmpRecord::new();
655 level2.add_field(LnmpField {
656 fid: 3,
657 value: LnmpValue::NestedRecord(Box::new(level3)),
658 });
659
660 let mut level1 = LnmpRecord::new();
661 level1.add_field(LnmpField {
662 fid: 4,
663 value: LnmpValue::NestedRecord(Box::new(level2)),
664 });
665
666 let result = encoder.encode_nested_record(&level1).unwrap();
667 assert!(!result.is_empty());
668 assert_eq!(result[0], 0x06); }
670
671 #[test]
672 fn test_encode_nested_record_depth_5() {
673 let encoder = BinaryNestedEncoder::new();
674
675 let mut level5 = LnmpRecord::new();
677 level5.add_field(LnmpField {
678 fid: 1,
679 value: LnmpValue::Int(100),
680 });
681
682 let mut level4 = LnmpRecord::new();
683 level4.add_field(LnmpField {
684 fid: 2,
685 value: LnmpValue::NestedRecord(Box::new(level5)),
686 });
687
688 let mut level3 = LnmpRecord::new();
689 level3.add_field(LnmpField {
690 fid: 3,
691 value: LnmpValue::NestedRecord(Box::new(level4)),
692 });
693
694 let mut level2 = LnmpRecord::new();
695 level2.add_field(LnmpField {
696 fid: 4,
697 value: LnmpValue::NestedRecord(Box::new(level3)),
698 });
699
700 let mut level1 = LnmpRecord::new();
701 level1.add_field(LnmpField {
702 fid: 5,
703 value: LnmpValue::NestedRecord(Box::new(level2)),
704 });
705
706 let result = encoder.encode_nested_record(&level1).unwrap();
707 assert!(!result.is_empty());
708 assert_eq!(result[0], 0x06); }
710
711 #[test]
712 fn test_encode_depth_limit_enforced_at_exact_limit() {
713 let config = NestedEncoderConfig::new().with_max_depth(2);
714 let encoder = BinaryNestedEncoder::with_config(config);
715
716 let mut level1 = LnmpRecord::new();
718 level1.add_field(LnmpField {
719 fid: 1,
720 value: LnmpValue::Int(42),
721 });
722
723 let result = encoder.encode_nested_record(&level1);
725 assert!(result.is_ok());
726
727 let mut inner = LnmpRecord::new();
729 inner.add_field(LnmpField {
730 fid: 1,
731 value: LnmpValue::Int(42),
732 });
733
734 let mut outer = LnmpRecord::new();
735 outer.add_field(LnmpField {
736 fid: 2,
737 value: LnmpValue::NestedRecord(Box::new(inner)),
738 });
739
740 let result = encoder.encode_nested_record(&outer);
742 assert!(result.is_ok());
743
744 let mut level3 = LnmpRecord::new();
746 level3.add_field(LnmpField {
747 fid: 1,
748 value: LnmpValue::Int(42),
749 });
750
751 let mut level2 = LnmpRecord::new();
752 level2.add_field(LnmpField {
753 fid: 2,
754 value: LnmpValue::NestedRecord(Box::new(level3)),
755 });
756
757 let mut level1_deep = LnmpRecord::new();
758 level1_deep.add_field(LnmpField {
759 fid: 3,
760 value: LnmpValue::NestedRecord(Box::new(level2)),
761 });
762
763 let result = encoder.encode_nested_record(&level1_deep);
765 assert!(result.is_err());
766 }
767
768 #[test]
769 fn test_encode_size_limit_enforced_incrementally() {
770 let config = NestedEncoderConfig::new().with_max_record_size(Some(50));
771 let encoder = BinaryNestedEncoder::with_config(config);
772
773 let mut record = LnmpRecord::new();
774 for i in 0..20 {
776 record.add_field(LnmpField {
777 fid: i,
778 value: LnmpValue::String("test".to_string()),
779 });
780 }
781
782 let result = encoder.encode_nested_record(&record);
783 assert!(result.is_err());
784 match result {
785 Err(BinaryError::RecordSizeExceeded { .. }) => {}
786 _ => panic!("Expected RecordSizeExceeded error"),
787 }
788 }
789
790 #[test]
791 fn test_encode_canonical_ordering_at_all_levels() {
792 let encoder = BinaryNestedEncoder::new();
793
794 let mut inner = LnmpRecord::new();
796 inner.add_field(LnmpField {
797 fid: 10,
798 value: LnmpValue::Int(3),
799 });
800 inner.add_field(LnmpField {
801 fid: 2,
802 value: LnmpValue::Int(1),
803 });
804 inner.add_field(LnmpField {
805 fid: 5,
806 value: LnmpValue::Int(2),
807 });
808
809 let mut outer = LnmpRecord::new();
810 outer.add_field(LnmpField {
811 fid: 20,
812 value: LnmpValue::String("last".to_string()),
813 });
814 outer.add_field(LnmpField {
815 fid: 1,
816 value: LnmpValue::NestedRecord(Box::new(inner)),
817 });
818 outer.add_field(LnmpField {
819 fid: 15,
820 value: LnmpValue::String("middle".to_string()),
821 });
822
823 let result = encoder.encode_nested_record(&outer).unwrap();
824
825 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x03); assert_eq!(result[2], 0x01); }
830
831 #[test]
832 fn test_encode_empty_nested_records_at_multiple_levels() {
833 let encoder = BinaryNestedEncoder::new();
834
835 let inner = LnmpRecord::new(); let mut outer = LnmpRecord::new();
837 outer.add_field(LnmpField {
838 fid: 1,
839 value: LnmpValue::NestedRecord(Box::new(inner)),
840 });
841
842 let result = encoder.encode_nested_record(&outer).unwrap();
843
844 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x01); assert_eq!(result[2], 0x01); assert_eq!(result[3], 0x06); assert_eq!(result[4], 0x00); }
850
851 #[test]
852 fn test_encode_empty_nested_arrays() {
853 let encoder = BinaryNestedEncoder::new();
854
855 let mut record = LnmpRecord::new();
856 record.add_field(LnmpField {
857 fid: 1,
858 value: LnmpValue::NestedArray(vec![]),
859 });
860
861 let result = encoder.encode_nested_record(&record).unwrap();
862
863 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x01); assert_eq!(result[2], 0x01); assert_eq!(result[3], 0x07); assert_eq!(result[4], 0x00); }
869
870 #[test]
871 fn test_encode_nested_array_with_canonical_ordering() {
872 let encoder = BinaryNestedEncoder::new();
873
874 let mut record1 = LnmpRecord::new();
876 record1.add_field(LnmpField {
877 fid: 10,
878 value: LnmpValue::Int(2),
879 });
880 record1.add_field(LnmpField {
881 fid: 5,
882 value: LnmpValue::Int(1),
883 });
884
885 let mut record2 = LnmpRecord::new();
886 record2.add_field(LnmpField {
887 fid: 20,
888 value: LnmpValue::Int(4),
889 });
890 record2.add_field(LnmpField {
891 fid: 15,
892 value: LnmpValue::Int(3),
893 });
894
895 let result = encoder.encode_nested_array(&[record1, record2]).unwrap();
896
897 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x02); assert_eq!(result[2], 0x06); assert_eq!(result[3], 0x02); assert_eq!(result[4], 0x05); }
906
907 #[test]
908 fn test_encode_mixed_primitive_and_nested_fields() {
909 let encoder = BinaryNestedEncoder::new();
910
911 let mut inner = LnmpRecord::new();
912 inner.add_field(LnmpField {
913 fid: 1,
914 value: LnmpValue::String("inner".to_string()),
915 });
916
917 let mut outer = LnmpRecord::new();
918 outer.add_field(LnmpField {
919 fid: 1,
920 value: LnmpValue::Int(42),
921 });
922 outer.add_field(LnmpField {
923 fid: 2,
924 value: LnmpValue::NestedRecord(Box::new(inner)),
925 });
926 outer.add_field(LnmpField {
927 fid: 3,
928 value: LnmpValue::Bool(true),
929 });
930
931 let result = encoder.encode_nested_record(&outer).unwrap();
932
933 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x03); }
936
937 #[test]
938 fn test_encode_all_primitive_types_in_nested_record() {
939 let encoder = BinaryNestedEncoder::new();
940
941 let mut record = LnmpRecord::new();
942 record.add_field(LnmpField {
943 fid: 1,
944 value: LnmpValue::Int(-42),
945 });
946 record.add_field(LnmpField {
947 fid: 2,
948 value: LnmpValue::Float(3.14),
949 });
950 record.add_field(LnmpField {
951 fid: 3,
952 value: LnmpValue::Bool(false),
953 });
954 record.add_field(LnmpField {
955 fid: 4,
956 value: LnmpValue::String("test".to_string()),
957 });
958 record.add_field(LnmpField {
959 fid: 5,
960 value: LnmpValue::StringArray(vec!["a".to_string(), "b".to_string()]),
961 });
962
963 let result = encoder.encode_nested_record(&record).unwrap();
964
965 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x05); }
968}