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::NestedRecord(record) => {
314 self.encode_nested_record_with_depth(record, current_depth)
315 }
316 LnmpValue::NestedArray(records) => {
317 self.encode_nested_array_with_depth(records, current_depth)
318 }
319 }
320 }
321}
322
323impl Default for BinaryNestedEncoder {
324 fn default() -> Self {
325 Self::new()
326 }
327}
328
329#[cfg(test)]
330mod tests {
331 #![allow(clippy::approx_constant)]
332
333 use super::*;
334 use lnmp_core::LnmpField;
335
336 #[test]
337 fn test_nested_encoder_config_default() {
338 let config = NestedEncoderConfig::default();
339 assert_eq!(config.max_depth, 32);
340 assert_eq!(config.max_record_size, None);
341 assert!(!config.validate_canonical);
342 }
343
344 #[test]
345 fn test_nested_encoder_config_builder() {
346 let config = NestedEncoderConfig::new()
347 .with_max_depth(16)
348 .with_max_record_size(Some(1024))
349 .with_validate_canonical(true);
350
351 assert_eq!(config.max_depth, 16);
352 assert_eq!(config.max_record_size, Some(1024));
353 assert!(config.validate_canonical);
354 }
355
356 #[test]
357 fn test_encode_empty_nested_record() {
358 let encoder = BinaryNestedEncoder::new();
359 let record = LnmpRecord::new();
360
361 let result = encoder.encode_nested_record(&record).unwrap();
362
363 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x00); assert_eq!(result.len(), 2);
367 }
368
369 #[test]
370 fn test_encode_single_level_nested_record() {
371 let encoder = BinaryNestedEncoder::new();
372 let mut record = LnmpRecord::new();
373 record.add_field(LnmpField {
374 fid: 1,
375 value: LnmpValue::Int(42),
376 });
377 record.add_field(LnmpField {
378 fid: 2,
379 value: LnmpValue::String("test".to_string()),
380 });
381
382 let result = encoder.encode_nested_record(&record).unwrap();
383
384 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x02); }
388
389 #[test]
390 fn test_encode_nested_record_canonical_ordering() {
391 let encoder = BinaryNestedEncoder::new();
392 let mut record = LnmpRecord::new();
393 record.add_field(LnmpField {
395 fid: 10,
396 value: LnmpValue::Int(3),
397 });
398 record.add_field(LnmpField {
399 fid: 2,
400 value: LnmpValue::Int(1),
401 });
402 record.add_field(LnmpField {
403 fid: 5,
404 value: LnmpValue::Int(2),
405 });
406
407 let result = encoder.encode_nested_record(&record).unwrap();
408
409 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x03); assert_eq!(result[2], 0x02); }
417
418 #[test]
419 fn test_encode_empty_nested_array() {
420 let encoder = BinaryNestedEncoder::new();
421 let records: Vec<LnmpRecord> = vec![];
422
423 let result = encoder.encode_nested_array(&records).unwrap();
424
425 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x00); assert_eq!(result.len(), 2);
429 }
430
431 #[test]
432 fn test_encode_nested_array_single_record() {
433 let encoder = BinaryNestedEncoder::new();
434 let mut record = LnmpRecord::new();
435 record.add_field(LnmpField {
436 fid: 1,
437 value: LnmpValue::Int(42),
438 });
439
440 let result = encoder.encode_nested_array(&[record]).unwrap();
441
442 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x01); assert_eq!(result[2], 0x06); }
448
449 #[test]
450 fn test_encode_nested_array_multiple_records() {
451 let encoder = BinaryNestedEncoder::new();
452 let mut record1 = LnmpRecord::new();
453 record1.add_field(LnmpField {
454 fid: 1,
455 value: LnmpValue::Int(1),
456 });
457
458 let mut record2 = LnmpRecord::new();
459 record2.add_field(LnmpField {
460 fid: 1,
461 value: LnmpValue::Int(2),
462 });
463
464 let result = encoder.encode_nested_array(&[record1, record2]).unwrap();
465
466 assert_eq!(result[0], 0x07); assert_eq!(result[1], 0x02); }
470
471 #[test]
472 fn test_encode_depth_limit_exceeded() {
473 let config = NestedEncoderConfig::new().with_max_depth(2);
474 let encoder = BinaryNestedEncoder::with_config(config);
475
476 let mut level3 = LnmpRecord::new();
478 level3.add_field(LnmpField {
479 fid: 1,
480 value: LnmpValue::Int(42),
481 });
482
483 let mut level2 = LnmpRecord::new();
484 level2.add_field(LnmpField {
485 fid: 2,
486 value: LnmpValue::NestedRecord(Box::new(level3)),
487 });
488
489 let mut level1 = LnmpRecord::new();
490 level1.add_field(LnmpField {
491 fid: 3,
492 value: LnmpValue::NestedRecord(Box::new(level2)),
493 });
494
495 let result = encoder.encode_nested_record(&level1);
496
497 assert!(result.is_err());
498 match result {
499 Err(BinaryError::NestingDepthExceeded { depth, max }) => {
500 assert_eq!(max, 2);
501 assert!(depth >= 2);
502 }
503 _ => panic!("Expected NestingDepthExceeded error"),
504 }
505 }
506
507 #[test]
508 fn test_encode_size_limit_exceeded() {
509 let config = NestedEncoderConfig::new().with_max_record_size(Some(10));
510 let encoder = BinaryNestedEncoder::with_config(config);
511
512 let mut record = LnmpRecord::new();
513 for i in 0..100 {
515 record.add_field(LnmpField {
516 fid: i,
517 value: LnmpValue::String("test".to_string()),
518 });
519 }
520
521 let result = encoder.encode_nested_record(&record);
522
523 assert!(result.is_err());
524 match result {
525 Err(BinaryError::RecordSizeExceeded { size, max }) => {
526 assert_eq!(max, 10);
527 assert!(size > 10);
528 }
529 _ => panic!("Expected RecordSizeExceeded error"),
530 }
531 }
532
533 #[test]
534 fn test_encode_multi_level_nested_record() {
535 let encoder = BinaryNestedEncoder::new();
536
537 let mut inner_record = LnmpRecord::new();
539 inner_record.add_field(LnmpField {
540 fid: 1,
541 value: LnmpValue::Int(42),
542 });
543
544 let mut outer_record = LnmpRecord::new();
545 outer_record.add_field(LnmpField {
546 fid: 2,
547 value: LnmpValue::NestedRecord(Box::new(inner_record)),
548 });
549
550 let result = encoder.encode_nested_record(&outer_record).unwrap();
551
552 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x01); assert_eq!(result[2], 0x02); assert_eq!(result[3], 0x06); }
560
561 #[test]
562 fn test_encode_nested_record_depth_2() {
563 let encoder = BinaryNestedEncoder::new();
564
565 let mut level2 = LnmpRecord::new();
567 level2.add_field(LnmpField {
568 fid: 1,
569 value: LnmpValue::Int(100),
570 });
571
572 let mut level1 = LnmpRecord::new();
573 level1.add_field(LnmpField {
574 fid: 2,
575 value: LnmpValue::NestedRecord(Box::new(level2)),
576 });
577
578 let result = encoder.encode_nested_record(&level1).unwrap();
579 assert!(!result.is_empty());
580 assert_eq!(result[0], 0x06); }
582
583 #[test]
584 fn test_encode_nested_record_depth_3() {
585 let encoder = BinaryNestedEncoder::new();
586
587 let mut level3 = LnmpRecord::new();
589 level3.add_field(LnmpField {
590 fid: 1,
591 value: LnmpValue::Int(100),
592 });
593
594 let mut level2 = LnmpRecord::new();
595 level2.add_field(LnmpField {
596 fid: 2,
597 value: LnmpValue::NestedRecord(Box::new(level3)),
598 });
599
600 let mut level1 = LnmpRecord::new();
601 level1.add_field(LnmpField {
602 fid: 3,
603 value: LnmpValue::NestedRecord(Box::new(level2)),
604 });
605
606 let result = encoder.encode_nested_record(&level1).unwrap();
607 assert!(!result.is_empty());
608 assert_eq!(result[0], 0x06); }
610
611 #[test]
612 fn test_encode_nested_record_depth_4() {
613 let encoder = BinaryNestedEncoder::new();
614
615 let mut level4 = LnmpRecord::new();
617 level4.add_field(LnmpField {
618 fid: 1,
619 value: LnmpValue::Int(100),
620 });
621
622 let mut level3 = LnmpRecord::new();
623 level3.add_field(LnmpField {
624 fid: 2,
625 value: LnmpValue::NestedRecord(Box::new(level4)),
626 });
627
628 let mut level2 = LnmpRecord::new();
629 level2.add_field(LnmpField {
630 fid: 3,
631 value: LnmpValue::NestedRecord(Box::new(level3)),
632 });
633
634 let mut level1 = LnmpRecord::new();
635 level1.add_field(LnmpField {
636 fid: 4,
637 value: LnmpValue::NestedRecord(Box::new(level2)),
638 });
639
640 let result = encoder.encode_nested_record(&level1).unwrap();
641 assert!(!result.is_empty());
642 assert_eq!(result[0], 0x06); }
644
645 #[test]
646 fn test_encode_nested_record_depth_5() {
647 let encoder = BinaryNestedEncoder::new();
648
649 let mut level5 = LnmpRecord::new();
651 level5.add_field(LnmpField {
652 fid: 1,
653 value: LnmpValue::Int(100),
654 });
655
656 let mut level4 = LnmpRecord::new();
657 level4.add_field(LnmpField {
658 fid: 2,
659 value: LnmpValue::NestedRecord(Box::new(level5)),
660 });
661
662 let mut level3 = LnmpRecord::new();
663 level3.add_field(LnmpField {
664 fid: 3,
665 value: LnmpValue::NestedRecord(Box::new(level4)),
666 });
667
668 let mut level2 = LnmpRecord::new();
669 level2.add_field(LnmpField {
670 fid: 4,
671 value: LnmpValue::NestedRecord(Box::new(level3)),
672 });
673
674 let mut level1 = LnmpRecord::new();
675 level1.add_field(LnmpField {
676 fid: 5,
677 value: LnmpValue::NestedRecord(Box::new(level2)),
678 });
679
680 let result = encoder.encode_nested_record(&level1).unwrap();
681 assert!(!result.is_empty());
682 assert_eq!(result[0], 0x06); }
684
685 #[test]
686 fn test_encode_depth_limit_enforced_at_exact_limit() {
687 let config = NestedEncoderConfig::new().with_max_depth(2);
688 let encoder = BinaryNestedEncoder::with_config(config);
689
690 let mut level1 = LnmpRecord::new();
692 level1.add_field(LnmpField {
693 fid: 1,
694 value: LnmpValue::Int(42),
695 });
696
697 let result = encoder.encode_nested_record(&level1);
699 assert!(result.is_ok());
700
701 let mut inner = LnmpRecord::new();
703 inner.add_field(LnmpField {
704 fid: 1,
705 value: LnmpValue::Int(42),
706 });
707
708 let mut outer = LnmpRecord::new();
709 outer.add_field(LnmpField {
710 fid: 2,
711 value: LnmpValue::NestedRecord(Box::new(inner)),
712 });
713
714 let result = encoder.encode_nested_record(&outer);
716 assert!(result.is_ok());
717
718 let mut level3 = LnmpRecord::new();
720 level3.add_field(LnmpField {
721 fid: 1,
722 value: LnmpValue::Int(42),
723 });
724
725 let mut level2 = LnmpRecord::new();
726 level2.add_field(LnmpField {
727 fid: 2,
728 value: LnmpValue::NestedRecord(Box::new(level3)),
729 });
730
731 let mut level1_deep = LnmpRecord::new();
732 level1_deep.add_field(LnmpField {
733 fid: 3,
734 value: LnmpValue::NestedRecord(Box::new(level2)),
735 });
736
737 let result = encoder.encode_nested_record(&level1_deep);
739 assert!(result.is_err());
740 }
741
742 #[test]
743 fn test_encode_size_limit_enforced_incrementally() {
744 let config = NestedEncoderConfig::new().with_max_record_size(Some(50));
745 let encoder = BinaryNestedEncoder::with_config(config);
746
747 let mut record = LnmpRecord::new();
748 for i in 0..20 {
750 record.add_field(LnmpField {
751 fid: i,
752 value: LnmpValue::String("test".to_string()),
753 });
754 }
755
756 let result = encoder.encode_nested_record(&record);
757 assert!(result.is_err());
758 match result {
759 Err(BinaryError::RecordSizeExceeded { .. }) => {}
760 _ => panic!("Expected RecordSizeExceeded error"),
761 }
762 }
763
764 #[test]
765 fn test_encode_canonical_ordering_at_all_levels() {
766 let encoder = BinaryNestedEncoder::new();
767
768 let mut inner = LnmpRecord::new();
770 inner.add_field(LnmpField {
771 fid: 10,
772 value: LnmpValue::Int(3),
773 });
774 inner.add_field(LnmpField {
775 fid: 2,
776 value: LnmpValue::Int(1),
777 });
778 inner.add_field(LnmpField {
779 fid: 5,
780 value: LnmpValue::Int(2),
781 });
782
783 let mut outer = LnmpRecord::new();
784 outer.add_field(LnmpField {
785 fid: 20,
786 value: LnmpValue::String("last".to_string()),
787 });
788 outer.add_field(LnmpField {
789 fid: 1,
790 value: LnmpValue::NestedRecord(Box::new(inner)),
791 });
792 outer.add_field(LnmpField {
793 fid: 15,
794 value: LnmpValue::String("middle".to_string()),
795 });
796
797 let result = encoder.encode_nested_record(&outer).unwrap();
798
799 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x03); assert_eq!(result[2], 0x01); }
804
805 #[test]
806 fn test_encode_empty_nested_records_at_multiple_levels() {
807 let encoder = BinaryNestedEncoder::new();
808
809 let inner = LnmpRecord::new(); let mut outer = LnmpRecord::new();
811 outer.add_field(LnmpField {
812 fid: 1,
813 value: LnmpValue::NestedRecord(Box::new(inner)),
814 });
815
816 let result = encoder.encode_nested_record(&outer).unwrap();
817
818 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); }
824
825 #[test]
826 fn test_encode_empty_nested_arrays() {
827 let encoder = BinaryNestedEncoder::new();
828
829 let mut record = LnmpRecord::new();
830 record.add_field(LnmpField {
831 fid: 1,
832 value: LnmpValue::NestedArray(vec![]),
833 });
834
835 let result = encoder.encode_nested_record(&record).unwrap();
836
837 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); }
843
844 #[test]
845 fn test_encode_nested_array_with_canonical_ordering() {
846 let encoder = BinaryNestedEncoder::new();
847
848 let mut record1 = LnmpRecord::new();
850 record1.add_field(LnmpField {
851 fid: 10,
852 value: LnmpValue::Int(2),
853 });
854 record1.add_field(LnmpField {
855 fid: 5,
856 value: LnmpValue::Int(1),
857 });
858
859 let mut record2 = LnmpRecord::new();
860 record2.add_field(LnmpField {
861 fid: 20,
862 value: LnmpValue::Int(4),
863 });
864 record2.add_field(LnmpField {
865 fid: 15,
866 value: LnmpValue::Int(3),
867 });
868
869 let result = encoder.encode_nested_array(&[record1, record2]).unwrap();
870
871 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); }
880
881 #[test]
882 fn test_encode_mixed_primitive_and_nested_fields() {
883 let encoder = BinaryNestedEncoder::new();
884
885 let mut inner = LnmpRecord::new();
886 inner.add_field(LnmpField {
887 fid: 1,
888 value: LnmpValue::String("inner".to_string()),
889 });
890
891 let mut outer = LnmpRecord::new();
892 outer.add_field(LnmpField {
893 fid: 1,
894 value: LnmpValue::Int(42),
895 });
896 outer.add_field(LnmpField {
897 fid: 2,
898 value: LnmpValue::NestedRecord(Box::new(inner)),
899 });
900 outer.add_field(LnmpField {
901 fid: 3,
902 value: LnmpValue::Bool(true),
903 });
904
905 let result = encoder.encode_nested_record(&outer).unwrap();
906
907 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x03); }
910
911 #[test]
912 fn test_encode_all_primitive_types_in_nested_record() {
913 let encoder = BinaryNestedEncoder::new();
914
915 let mut record = LnmpRecord::new();
916 record.add_field(LnmpField {
917 fid: 1,
918 value: LnmpValue::Int(-42),
919 });
920 record.add_field(LnmpField {
921 fid: 2,
922 value: LnmpValue::Float(3.14),
923 });
924 record.add_field(LnmpField {
925 fid: 3,
926 value: LnmpValue::Bool(false),
927 });
928 record.add_field(LnmpField {
929 fid: 4,
930 value: LnmpValue::String("test".to_string()),
931 });
932 record.add_field(LnmpField {
933 fid: 5,
934 value: LnmpValue::StringArray(vec!["a".to_string(), "b".to_string()]),
935 });
936
937 let result = encoder.encode_nested_record(&record).unwrap();
938
939 assert_eq!(result[0], 0x06); assert_eq!(result[1], 0x05); }
942}