1#![expect(unsafe_code)]
22#![warn(clippy::std_instead_of_alloc)]
23#![warn(clippy::std_instead_of_core)]
24#![warn(clippy::alloc_instead_of_core)]
25#![no_std]
26
27extern crate alloc;
28extern crate self as mesh_protobuf;
29#[cfg(feature = "std")]
30extern crate std;
31
32pub mod buffer;
33mod encode_with;
34pub mod encoding;
35pub mod inplace;
36pub mod message;
37pub mod oneof;
38#[cfg(feature = "prost")]
39pub mod prost;
40pub mod protobuf;
41pub mod protofile;
42pub mod table;
43mod time;
44pub mod transparent;
45
46pub use encode_with::EncodeAs;
47pub use mesh_derive::Protobuf;
48pub use time::Timestamp;
49
50use self::table::decode::DecoderEntry;
51use self::table::encode::EncoderEntry;
52use alloc::boxed::Box;
53use alloc::fmt;
54use alloc::vec::Vec;
55use core::cell::RefCell;
56use core::mem::MaybeUninit;
57use core::num::Wrapping;
58use inplace::InplaceOption;
59use protofile::DescribeMessage;
60use protofile::MessageDescription;
61use protofile::TypeUrl;
62
63#[diagnostic::on_unimplemented(
66 message = "`{Self}` cannot be encoded as a mesh message",
67 note = "consider deriving the necessary trait on `{Self}` with one of:
68 #[derive(MeshPayload)]
69 #[derive(Protobuf)]",
70 note = "alternatively, consider using an explicit encoder with #[mesh(encoding = \"MyEncoding\")]"
71)]
72pub trait DefaultEncoding {
73 type Encoding;
80}
81
82pub trait Protobuf: DefaultEncoding<Encoding = <Self as Protobuf>::Encoding> + Sized {
84 type Encoding: MessageEncode<Self, NoResources>
86 + for<'a> MessageDecode<'a, Self, NoResources>
87 + FieldEncode<Self, NoResources>
88 + for<'a> FieldDecode<'a, Self, NoResources>;
89}
90
91impl<T> Protobuf for T
92where
93 T: DefaultEncoding,
94 T::Encoding: MessageEncode<T, NoResources>
95 + for<'a> MessageDecode<'a, T, NoResources>
96 + FieldEncode<T, NoResources>
97 + for<'a> FieldDecode<'a, T, NoResources>,
98{
99 type Encoding = <T as DefaultEncoding>::Encoding;
100}
101
102pub trait DescribedProtobuf: Protobuf {
105 const DESCRIPTION: MessageDescription<'static>;
107 const TYPE_URL: TypeUrl<'static> = Self::DESCRIPTION.type_url();
109}
110
111impl<T: DefaultEncoding + Protobuf> DescribedProtobuf for T
112where
113 <T as DefaultEncoding>::Encoding: DescribeMessage<T>,
114{
115 const DESCRIPTION: MessageDescription<'static> =
116 <<T as DefaultEncoding>::Encoding as DescribeMessage<T>>::DESCRIPTION;
117}
118
119pub trait MessageEncode<T, R>: Sized {
125 fn write_message(item: T, writer: protobuf::MessageWriter<'_, '_, R>);
127
128 fn compute_message_size(item: &mut T, sizer: protobuf::MessageSizer<'_>);
137}
138
139pub trait MessageDecode<'a, T, R>: Sized {
145 fn read_message(
147 item: &mut InplaceOption<'_, T>,
148 reader: protobuf::MessageReader<'a, '_, R>,
149 ) -> Result<()>;
150}
151
152pub trait FieldEncode<T, R>: Sized {
158 fn write_field(item: T, writer: protobuf::FieldWriter<'_, '_, R>);
160
161 fn compute_field_size(item: &mut T, sizer: protobuf::FieldSizer<'_>);
170
171 fn packed<'a>() -> Option<&'a dyn PackedEncode<T>>
174 where
175 T: 'a,
176 {
177 None
178 }
179
180 fn wrap_in_sequence() -> bool {
186 false
187 }
188
189 fn write_field_in_sequence(item: T, writer: &mut protobuf::SequenceWriter<'_, '_, R>) {
192 if Self::wrap_in_sequence() {
193 WrappedField::<Self>::write_field(item, writer.field())
194 } else {
195 Self::write_field(item, writer.field())
196 }
197 }
198
199 fn compute_field_size_in_sequence(item: &mut T, sizer: &mut protobuf::SequenceSizer<'_>) {
202 if Self::wrap_in_sequence() {
203 WrappedField::<Self>::compute_field_size(item, sizer.field())
204 } else {
205 Self::compute_field_size(item, sizer.field())
206 }
207 }
208
209 const ENTRY: EncoderEntry<T, R> = EncoderEntry::custom::<Self>();
214}
215
216pub trait PackedEncode<T> {
218 fn write_packed(&self, data: &[T], writer: protobuf::PackedWriter<'_, '_>);
220
221 fn compute_packed_size(&self, data: &[T], sizer: protobuf::PackedSizer<'_>);
223
224 fn must_pack(&self) -> bool;
229}
230
231pub trait FieldDecode<'a, T, R>: Sized {
237 fn read_field(
239 item: &mut InplaceOption<'_, T>,
240 reader: protobuf::FieldReader<'a, '_, R>,
241 ) -> Result<()>;
242
243 fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()>;
248
249 fn packed<'p, C: CopyExtend<T>>() -> Option<&'p dyn PackedDecode<'a, T, C>>
252 where
253 T: 'p,
254 {
255 None
256 }
257
258 fn wrap_in_sequence() -> bool {
261 false
262 }
263
264 fn read_field_in_sequence(
267 item: &mut InplaceOption<'_, T>,
268 reader: protobuf::FieldReader<'a, '_, R>,
269 ) -> Result<()> {
270 if Self::wrap_in_sequence() {
271 WrappedField::<Self>::read_field(item, reader)
272 } else {
273 Self::read_field(item, reader)
274 }
275 }
276
277 const ENTRY: DecoderEntry<'a, T, R> = DecoderEntry::custom::<Self>();
282}
283
284pub trait PackedDecode<'a, T, C> {
286 fn read_packed(&self, data: &mut C, reader: &mut protobuf::PackedReader<'a>) -> Result<()>;
288
289 fn must_pack(&self) -> bool;
292}
293
294pub trait CopyExtend<T> {
296 fn push(&mut self, item: T)
298 where
299 T: Copy;
300
301 fn extend_from_slice(&mut self, items: &[T])
303 where
304 T: Copy;
305}
306
307impl<T> CopyExtend<T> for Vec<T> {
308 fn push(&mut self, item: T)
309 where
310 T: Copy,
311 {
312 self.push(item);
313 }
314
315 fn extend_from_slice(&mut self, items: &[T])
316 where
317 T: Copy,
318 {
319 self.extend_from_slice(items);
320 }
321}
322
323struct WrappedField<E>(pub E);
326
327impl<T, R, E: FieldEncode<T, R>> FieldEncode<T, R> for WrappedField<E> {
328 fn write_field(item: T, writer: protobuf::FieldWriter<'_, '_, R>) {
329 writer.message(|mut writer| E::write_field(item, writer.field(1)));
330 }
331
332 fn compute_field_size(item: &mut T, sizer: protobuf::FieldSizer<'_>) {
333 sizer.message(|mut sizer| E::compute_field_size(item, sizer.field(1)));
334 }
335}
336
337impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, T, R> for WrappedField<E> {
338 fn read_field(
339 item: &mut InplaceOption<'_, T>,
340 reader: protobuf::FieldReader<'a, '_, R>,
341 ) -> Result<()> {
342 for field in reader.message()? {
343 let (number, reader) = field?;
344 if number == 1 {
345 E::read_field(item, reader)?;
346 }
347 }
348 if item.is_none() {
349 E::default_field(item)?;
350 }
351 Ok(())
352 }
353
354 fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
355 E::default_field(item)
356 }
357}
358
359pub fn encode<T: DefaultEncoding>(message: T) -> Vec<u8>
361where
362 T::Encoding: MessageEncode<T, NoResources>,
363{
364 protobuf::Encoder::new(message).encode().0
365}
366
367pub fn decode<'a, T: DefaultEncoding>(data: &'a [u8]) -> Result<T>
369where
370 T::Encoding: MessageDecode<'a, T, NoResources>,
371{
372 inplace_none!(message: T);
373 protobuf::decode_with::<T::Encoding, _, _>(&mut message, data, &mut [])?;
374 Ok(message.take().expect("should be constructed"))
375}
376
377pub fn merge<'a, T: DefaultEncoding>(value: T, data: &'a [u8]) -> Result<T>
379where
380 T::Encoding: MessageDecode<'a, T, NoResources>,
381{
382 inplace_some!(value);
383 protobuf::decode_with::<T::Encoding, _, _>(&mut value, data, &mut [])?;
384 Ok(value.take().expect("should be constructed"))
385}
386
387pub enum NoResources {}
390
391#[derive(Debug)]
394pub struct SerializedMessage<R = NoResources> {
395 pub data: Vec<u8>,
397 pub resources: Vec<R>,
399}
400
401impl<R> Default for SerializedMessage<R> {
402 fn default() -> Self {
403 Self {
404 data: Default::default(),
405 resources: Default::default(),
406 }
407 }
408}
409
410impl<R> SerializedMessage<R> {
411 pub fn from_message<T: DefaultEncoding>(t: T) -> Self
413 where
414 T::Encoding: MessageEncode<T, R>,
415 {
416 let (data, resources) = protobuf::Encoder::new(t).encode();
417 Self { data, resources }
418 }
419
420 pub fn into_message<T: DefaultEncoding>(self) -> Result<T>
422 where
423 T::Encoding: for<'a> MessageDecode<'a, T, R>,
424 {
425 let (data, mut resources) = self.prep_decode();
426 inplace_none!(message: T);
427 protobuf::decode_with::<T::Encoding, _, _>(&mut message, &data, &mut resources)?;
428 Ok(message.take().expect("should be constructed"))
429 }
430
431 fn prep_decode(self) -> (Vec<u8>, Vec<Option<R>>) {
432 let data = self.data;
433 let resources = self.resources.into_iter().map(Some).collect();
434 (data, resources)
435 }
436}
437
438#[derive(Debug)]
440pub struct Error(Box<ErrorInner>);
441
442#[derive(Debug)]
443struct ErrorInner {
444 types: Vec<&'static str>,
445 err: Box<dyn core::error::Error + Send + Sync>,
446}
447
448#[derive(Debug, thiserror::Error)]
450enum DecodeError {
451 #[error("expected a message")]
452 ExpectedMessage,
453 #[error("expected a resource")]
454 ExpectedResource,
455 #[error("expected a varint")]
456 ExpectedVarInt,
457 #[error("expected a fixed64")]
458 ExpectedFixed64,
459 #[error("expected a fixed32")]
460 ExpectedFixed32,
461 #[error("expected a byte array")]
462 ExpectedByteArray,
463 #[error("field cannot exist")]
464 Unexpected,
465
466 #[error("eof parsing a varint")]
467 EofVarInt,
468 #[error("eof parsing a fixed64")]
469 EofFixed64,
470 #[error("eof parsing a fixed32")]
471 EofFixed32,
472 #[error("eof parsing a byte array")]
473 EofByteArray,
474
475 #[error("varint too big")]
476 VarIntTooBig,
477
478 #[error("missing resource")]
479 MissingResource,
480 #[error("invalid resource range")]
481 InvalidResourceRange,
482
483 #[error("unknown wire type {0}")]
484 UnknownWireType(u32),
485
486 #[error("invalid UTF-32 character")]
487 InvalidUtf32,
488 #[error("wrong buffer size for u128")]
489 BadU128,
490 #[error("wrong buffer size for ipv6 address")]
491 BadIpv6,
492 #[error("invalid UTF-8 string")]
493 InvalidUtf8(#[source] core::str::Utf8Error),
494 #[error("missing required field")]
495 MissingRequiredField,
496 #[error("wrong packed array length")]
497 BadPackedArrayLength,
498 #[error("wrong array length")]
499 BadArrayLength,
500
501 #[error("duration out of range")]
502 DurationRange,
503}
504
505impl Error {
506 pub fn new(error: impl Into<Box<dyn core::error::Error + Send + Sync>>) -> Self {
508 Self(Box::new(ErrorInner {
509 types: Vec::new(),
510 err: error.into(),
511 }))
512 }
513
514 pub fn typed<T>(mut self) -> Self {
516 self.0.types.push(core::any::type_name::<T>());
517 self
518 }
519}
520
521impl From<DecodeError> for Error {
522 fn from(kind: DecodeError) -> Self {
523 Self(Box::new(ErrorInner {
524 types: Vec::new(),
525 err: kind.into(),
526 }))
527 }
528}
529
530impl fmt::Display for Error {
531 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
532 if let Some(&ty) = self.0.types.last() {
533 write!(f, "decoding failed in {}", ty)?;
534 for &ty in self.0.types.iter().rev().skip(1) {
535 write!(f, "/{}", ty)?;
536 }
537 Ok(())
538 } else {
539 write!(f, "decoding failed")
540 }
541 }
542}
543
544impl core::error::Error for Error {
545 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
546 Some(self.0.err.as_ref())
547 }
548}
549
550pub trait ResultExt {
552 fn typed<T>(self) -> Self;
554}
555
556impl<T> ResultExt for Result<T> {
557 fn typed<U>(self) -> Self {
558 self.map_err(Error::typed::<U>)
559 }
560}
561
562pub type Result<T> = core::result::Result<T, Error>;
564
565#[cfg(test)]
566mod tests {
567 extern crate std;
568
569 use super::SerializedMessage;
570 use super::encode;
571 use crate::DecodeError;
572 use crate::FieldDecode;
573 use crate::FieldEncode;
574 use crate::NoResources;
575 use crate::decode;
576 use crate::encoding::BorrowedCowField;
577 use crate::encoding::OwningCowField;
578 use crate::encoding::VecField;
579 use crate::protobuf::read_varint;
580 use alloc::borrow::Cow;
581 use alloc::collections::BTreeMap;
582 use alloc::vec;
583 use core::convert::Infallible;
584 use core::error::Error;
585 use core::fmt::Write;
586 use core::net::Ipv4Addr;
587 use core::net::Ipv6Addr;
588 use core::num::NonZeroU32;
589 use core::str::FromStr as _;
590 use core::time::Duration;
591 use expect_test::Expect;
592 use expect_test::expect;
593 use mesh_derive::Protobuf;
594 use std::prelude::rust_2021::*;
595 use std::println;
596
597 pub(crate) fn as_expect_str(v: &[u8]) -> String {
598 let cooked = parsed_expect_str(v).unwrap_or_else(|e| alloc::format!("PARSE ERROR: {e}\n"));
599 let raw = hex_str(v);
600 alloc::format!("{cooked}raw: {raw}")
601 }
602
603 fn hex_str(v: &[u8]) -> String {
604 v.iter()
605 .map(|x| alloc::format!("{x:02x}"))
606 .collect::<Vec<_>>()
607 .join("")
608 }
609
610 fn parsed_expect_str(mut v: &[u8]) -> Result<String, crate::Error> {
611 let mut s = String::new();
612 while !v.is_empty() {
613 let key = read_varint(&mut v)?;
614 let wire_type = (key & 7) as u32;
615 let field_number = (key >> 3) as u32;
616 write!(s, "{field_number}: ").ok();
617 match wire_type {
618 0 => {
619 let n = read_varint(&mut v)?;
620 writeln!(s, "varint {n}").ok();
621 }
622 1 => {
623 let n = u64::from_le_bytes(
624 v.get(..8)
625 .ok_or(DecodeError::EofFixed64)?
626 .try_into()
627 .unwrap(),
628 );
629 writeln!(s, "fixed64 {n:#018x}").ok();
630 v = &v[8..];
631 }
632 2 => {
633 let len = read_varint(&mut v)? as usize;
634 let data = v.get(..len).ok_or(DecodeError::EofByteArray)?;
635 if !data.is_empty() && data.iter().all(|&x| matches!(x, 0x20..=0x7e)) {
636 let data = core::str::from_utf8(data).unwrap();
637 writeln!(s, "string \"{data}\"").ok();
638 } else {
639 let data = hex_str(data);
640 writeln!(s, "bytes <{data}>").ok();
641 }
642 v = &v[len..];
643 }
644 5 => {
645 let n = u32::from_le_bytes(
646 v.get(..4)
647 .ok_or(DecodeError::EofFixed32)?
648 .try_into()
649 .unwrap(),
650 );
651 writeln!(s, "fixed32 {n:#010x}").ok();
652 v = &v[4..];
653 }
654 n => Err(DecodeError::UnknownWireType(n))?,
655 }
656 }
657 if s.is_empty() {
658 writeln!(s, "empty").ok();
659 }
660 Ok(s)
661 }
662
663 #[track_caller]
667 fn assert_roundtrips_nondeterministic<T>(t: T) -> Vec<u8>
668 where
669 T: crate::DefaultEncoding + Clone + Eq + core::fmt::Debug,
670 T::Encoding:
671 crate::MessageEncode<T, NoResources> + for<'a> crate::MessageDecode<'a, T, NoResources>,
672 {
673 println!("{t:?}");
674 let v = encode(t.clone());
675 println!("{v:x?}");
676 let t2 = decode::<T>(&v).unwrap();
677 assert_eq!(t, t2);
678 v
679 }
680
681 #[track_caller]
682 fn assert_roundtrips<T>(t: T, expect: Expect)
683 where
684 T: crate::DefaultEncoding + Clone + Eq + core::fmt::Debug,
685 T::Encoding:
686 crate::MessageEncode<T, NoResources> + for<'a> crate::MessageDecode<'a, T, NoResources>,
687 {
688 let v = assert_roundtrips_nondeterministic(t);
689 expect.assert_eq(&as_expect_str(&v));
690 }
691
692 #[track_caller]
693 fn assert_field_roundtrips<T>(t: T, expect: Expect)
694 where
695 T: crate::DefaultEncoding + Clone + Eq + core::fmt::Debug,
696 T::Encoding: FieldEncode<T, NoResources> + for<'a> FieldDecode<'a, T, NoResources>,
697 {
698 assert_roundtrips((t,), expect);
699 }
700
701 #[test]
702 fn test_field() {
703 assert_field_roundtrips(
704 5u32,
705 expect!([r#"
706 1: varint 5
707 raw: 0805"#]),
708 );
709 assert_field_roundtrips(
710 true,
711 expect!([r#"
712 1: varint 1
713 raw: 0801"#]),
714 );
715 assert_field_roundtrips(
716 "hi".to_string(),
717 expect!([r#"
718 1: string "hi"
719 raw: 0a026869"#]),
720 );
721 assert_field_roundtrips(
722 5u128,
723 expect!([r#"
724 1: bytes <05000000000000000000000000000000>
725 raw: 0a1005000000000000000000000000000000"#]),
726 );
727 assert_field_roundtrips(
728 (),
729 expect!([r#"
730 empty
731 raw: "#]),
732 );
733 assert_field_roundtrips(
734 (1, 2),
735 expect!([r#"
736 1: bytes <08021004>
737 raw: 0a0408021004"#]),
738 );
739 assert_field_roundtrips(
740 ("foo".to_string(), "bar".to_string()),
741 expect!([r#"
742 1: bytes <0a03666f6f1203626172>
743 raw: 0a0a0a03666f6f1203626172"#]),
744 );
745 assert_field_roundtrips(
746 [1, 2, 3],
747 expect!([r#"
748 1: bytes <020406>
749 raw: 0a03020406"#]),
750 );
751 assert_field_roundtrips(
752 ["abc".to_string(), "def".to_string()],
753 expect!([r#"
754 1: bytes <0a036162630a03646566>
755 raw: 0a0a0a036162630a03646566"#]),
756 );
757 assert_field_roundtrips(
758 Some(5),
759 expect!([r#"
760 1: varint 10
761 raw: 080a"#]),
762 );
763 assert_field_roundtrips(
764 Option::<u32>::None,
765 expect!([r#"
766 empty
767 raw: "#]),
768 );
769 assert_field_roundtrips(
770 vec![1, 2, 3],
771 expect!([r#"
772 1: bytes <020406>
773 raw: 0a03020406"#]),
774 );
775 assert_field_roundtrips(
776 vec!["abc".to_string(), "def".to_string()],
777 expect!([r#"
778 1: string "abc"
779 1: string "def"
780 raw: 0a036162630a03646566"#]),
781 );
782 assert_field_roundtrips(
783 Some(Some(true)),
784 expect!([r#"
785 1: bytes <0801>
786 raw: 0a020801"#]),
787 );
788 assert_field_roundtrips(
789 Some(Option::<bool>::None),
790 expect!([r#"
791 1: bytes <>
792 raw: 0a00"#]),
793 );
794 assert_field_roundtrips(
795 vec![None, Some(true), None],
796 expect!([r#"
797 1: bytes <>
798 1: bytes <0801>
799 1: bytes <>
800 raw: 0a000a0208010a00"#]),
801 );
802 #[cfg(feature = "std")]
803 assert_roundtrips_nondeterministic((std::collections::HashMap::from_iter([
804 (5u32, 6u32),
805 (4, 2),
806 ]),));
807 assert_field_roundtrips(
808 BTreeMap::from_iter([("hi".to_owned(), 6u32), ("hmm".to_owned(), 2)]),
809 expect!([r#"
810 1: bytes <0a0268691006>
811 1: bytes <0a03686d6d1002>
812 raw: 0a060a02686910060a070a03686d6d1002"#]),
813 );
814 assert_field_roundtrips(
815 Ipv4Addr::from_str("1.2.3.4").unwrap(),
816 expect!([r#"
817 1: fixed32 0x01020304
818 raw: 0d04030201"#]),
819 );
820 assert_field_roundtrips(
821 Ipv4Addr::UNSPECIFIED,
822 expect!([r#"
823 empty
824 raw: "#]),
825 );
826 assert_field_roundtrips(
827 Ipv6Addr::from_str("1:2:3:4:5:6:7:8").unwrap(),
828 expect!([r#"
829 1: bytes <00010002000300040005000600070008>
830 raw: 0a1000010002000300040005000600070008"#]),
831 );
832 assert_field_roundtrips(
833 Ipv6Addr::UNSPECIFIED,
834 expect!([r#"
835 empty
836 raw: "#]),
837 );
838 }
839
840 #[test]
841 fn test_nonzero() {
842 assert_field_roundtrips(
843 NonZeroU32::new(1).unwrap(),
844 expect!([r#"
845 1: varint 1
846 raw: 0801"#]),
847 );
848 assert_eq!(encode((5u32,)), encode((NonZeroU32::new(5).unwrap(),)));
849 assert_eq!(
850 decode::<(NonZeroU32,)>(&encode((Some(0u32),)))
851 .unwrap_err()
852 .source()
853 .unwrap()
854 .to_string(),
855 "value must be non-zero"
856 )
857 }
858
859 #[test]
860 fn test_derive_struct() {
861 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
862 struct Foo {
863 x: u32,
864 y: u32,
865 z: String,
866 w: Option<bool>,
867 }
868
869 let foo = Foo {
870 x: 5,
871 y: 104824,
872 z: "alphabet".to_owned(),
873 w: None,
874 };
875 assert_roundtrips(
876 foo,
877 expect!([r#"
878 1: varint 5
879 2: varint 104824
880 3: string "alphabet"
881 raw: 080510f8b2061a08616c706861626574"#]),
882 );
883 }
884
885 #[test]
886 fn test_nested_derive_struct() {
887 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
888 struct Foo {
889 x: u32,
890 y: u32,
891 b: Option<Bar>,
892 }
893
894 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
895 struct Bar {
896 a: Option<bool>,
897 b: u32,
898 }
899
900 let foo = Foo {
901 x: 5,
902 y: 104824,
903 b: Some(Bar {
904 a: Some(true),
905 b: 5,
906 }),
907 };
908 assert_roundtrips(
909 foo,
910 expect!([r#"
911 1: varint 5
912 2: varint 104824
913 3: bytes <08011005>
914 raw: 080510f8b2061a0408011005"#]),
915 );
916 }
917
918 #[test]
919 fn test_derive_enum() {
920 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
921 enum Foo {
922 A,
923 B(u32, String),
924 C { x: bool, y: u32 },
925 }
926
927 assert_roundtrips(
928 Foo::A,
929 expect!([r#"
930 1: bytes <>
931 raw: 0a00"#]),
932 );
933 assert_roundtrips(
934 Foo::B(12, "hi".to_owned()),
935 expect!([r#"
936 2: bytes <080c12026869>
937 raw: 1206080c12026869"#]),
938 );
939 assert_roundtrips(
940 Foo::C { x: true, y: 0 },
941 expect!([r#"
942 3: bytes <0801>
943 raw: 1a020801"#]),
944 );
945 assert_roundtrips(
946 Foo::C { x: false, y: 0 },
947 expect!([r#"
948 3: bytes <>
949 raw: 1a00"#]),
950 );
951 }
952
953 #[test]
954 fn test_vec() {
955 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
956 struct Foo {
957 u32: Vec<u32>,
958 u8: Vec<u8>,
959 vec_no_pack: Vec<(u32,)>,
960 vec_of_vec8: Vec<Vec<u8>>,
961 vec_of_vec32: Vec<Vec<u32>>,
962 vec_of_vec_no_pack: Vec<Vec<(u32,)>>,
963 }
964
965 let foo = Foo {
966 u32: vec![1, 2, 3, 4, 5],
967 u8: b"abcdefg".to_vec(),
968 vec_no_pack: vec![(1,), (2,), (3,), (4,), (5,)],
969 vec_of_vec8: vec![b"abc".to_vec(), b"def".to_vec()],
970 vec_of_vec32: vec![vec![1, 2, 3], vec![4, 5, 6]],
971 vec_of_vec_no_pack: vec![vec![(64,), (65,)], vec![(66,), (67,)]],
972 };
973 assert_roundtrips(
974 foo,
975 expect!([r#"
976 1: bytes <0102030405>
977 2: string "abcdefg"
978 3: bytes <0801>
979 3: bytes <0802>
980 3: bytes <0803>
981 3: bytes <0804>
982 3: bytes <0805>
983 4: string "abc"
984 4: string "def"
985 5: bytes <0a03010203>
986 5: bytes <0a03040506>
987 6: bytes <0a0208400a020841>
988 6: bytes <0a0208420a020843>
989 raw: 0a0501020304051207616263646566671a0208011a0208021a0208031a0208041a020805220361626322036465662a050a030102032a050a0304050632080a0208400a02084132080a0208420a020843"#]),
990 );
991 }
992
993 struct NoPackU32;
994
995 impl<R> FieldEncode<u32, R> for NoPackU32 {
996 fn write_field(item: u32, writer: crate::protobuf::FieldWriter<'_, '_, R>) {
997 writer.varint(item.into())
998 }
999
1000 fn compute_field_size(item: &mut u32, sizer: crate::protobuf::FieldSizer<'_>) {
1001 sizer.varint((*item).into())
1002 }
1003 }
1004
1005 impl<R> FieldDecode<'_, u32, R> for NoPackU32 {
1006 fn read_field(
1007 _item: &mut crate::inplace::InplaceOption<'_, u32>,
1008 _reader: crate::protobuf::FieldReader<'_, '_, R>,
1009 ) -> crate::Result<()> {
1010 unimplemented!()
1011 }
1012
1013 fn default_field(_item: &mut crate::inplace::InplaceOption<'_, u32>) -> crate::Result<()> {
1014 unimplemented!()
1015 }
1016 }
1017
1018 #[test]
1019 fn test_vec_alt() {
1020 {
1021 #[derive(Protobuf, Clone)]
1022 struct NoPack {
1023 #[mesh(encoding = "VecField<NoPackU32>")]
1024 v: Vec<u32>,
1025 }
1026
1027 #[derive(Protobuf)]
1028 struct CanPack {
1029 v: Vec<u32>,
1030 }
1031
1032 let no_pack = NoPack { v: vec![1, 2, 3] };
1033 let v = encode(no_pack.clone());
1034 println!("{v:x?}");
1035 let can_pack = decode::<CanPack>(&v).unwrap();
1036 assert_eq!(no_pack.v, can_pack.v);
1037 }
1038
1039 {
1040 #[derive(Protobuf, Clone)]
1041 struct NoPackNest {
1042 #[mesh(encoding = "VecField<VecField<NoPackU32>>")]
1043 v: Vec<Vec<u32>>,
1044 }
1045
1046 #[derive(Protobuf)]
1047 struct CanPackNest {
1048 v: Vec<Vec<u32>>,
1049 }
1050
1051 let no_pack = NoPackNest {
1052 v: vec![vec![1, 2, 3], vec![4, 5, 6]],
1053 };
1054 let v = encode(no_pack.clone());
1055 println!("{v:x?}");
1056 let can_pack = decode::<CanPackNest>(&v).unwrap();
1057 assert_eq!(no_pack.v, can_pack.v);
1058 }
1059 }
1060
1061 #[test]
1062 fn test_merge() {
1063 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
1064 struct Bar(u32);
1065
1066 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
1067 enum Enum {
1068 A(u32),
1069 B(Option<u32>, Vec<u8>),
1070 }
1071
1072 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
1073 struct Foo {
1074 x: u32,
1075 y: u32,
1076 z: String,
1077 w: Option<bool>,
1078 v: Vec<u32>,
1079 v8: Vec<u8>,
1080 vb: Vec<Bar>,
1081 e: Enum,
1082 }
1083
1084 let foo = Foo {
1085 x: 1,
1086 y: 2,
1087 z: "abc".to_string(),
1088 w: Some(true),
1089 v: vec![1, 2, 3],
1090 v8: b"xyz".to_vec(),
1091 vb: vec![Bar(1), Bar(2)],
1092 e: Enum::B(Some(1), b"abc".to_vec()),
1093 };
1094 assert_roundtrips(
1095 foo.clone(),
1096 expect!([r#"
1097 1: varint 1
1098 2: varint 2
1099 3: string "abc"
1100 4: varint 1
1101 5: bytes <010203>
1102 6: string "xyz"
1103 7: bytes <0801>
1104 7: bytes <0802>
1105 8: bytes <120708011203616263>
1106 raw: 080110021a0361626320012a03010203320378797a3a0208013a0208024209120708011203616263"#]),
1107 );
1108 let foo2 = Foo {
1109 x: 3,
1110 y: 4,
1111 z: "def".to_string(),
1112 w: None,
1113 v: vec![4, 5, 6],
1114 v8: b"uvw".to_vec(),
1115 vb: vec![Bar(3), Bar(4), Bar(5)],
1116 e: Enum::B(None, b"def".to_vec()),
1117 };
1118 assert_roundtrips(
1119 foo2.clone(),
1120 expect!([r#"
1121 1: varint 3
1122 2: varint 4
1123 3: string "def"
1124 5: bytes <040506>
1125 6: string "uvw"
1126 7: bytes <0803>
1127 7: bytes <0804>
1128 7: bytes <0805>
1129 8: bytes <12051203646566>
1130 raw: 080310041a036465662a0304050632037576773a0208033a0208043a020805420712051203646566"#]),
1131 );
1132 let foo3 = Foo {
1133 x: 3,
1134 y: 4,
1135 z: "def".to_string(),
1136 w: Some(true),
1137 v: vec![1, 2, 3, 4, 5, 6],
1138 v8: b"xyzuvw".to_vec(),
1139 vb: vec![Bar(1), Bar(2), Bar(3), Bar(4), Bar(5)],
1140 e: Enum::B(Some(1), b"abcdef".to_vec()),
1141 };
1142 assert_roundtrips(
1143 foo3.clone(),
1144 expect!([r#"
1145 1: varint 3
1146 2: varint 4
1147 3: string "def"
1148 4: varint 1
1149 5: bytes <010203040506>
1150 6: string "xyzuvw"
1151 7: bytes <0801>
1152 7: bytes <0802>
1153 7: bytes <0803>
1154 7: bytes <0804>
1155 7: bytes <0805>
1156 8: bytes <120a08011206616263646566>
1157 raw: 080310041a0364656620012a06010203040506320678797a7576773a0208013a0208023a0208033a0208043a020805420c120a08011206616263646566"#]),
1158 );
1159 let foo = super::merge(foo, &<SerializedMessage>::from_message(foo2).data).unwrap();
1160 assert_eq!(foo, foo3);
1161 }
1162
1163 #[test]
1164 fn test_alternate_encoding() {
1165 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
1166 struct Foo {
1167 sint32: i32,
1168 #[mesh(encoding = "mesh_protobuf::encoding::VarintField")]
1169 int32: i32,
1170 }
1171 assert_roundtrips(
1172 Foo {
1173 int32: -1,
1174 sint32: -1,
1175 },
1176 expect!([r#"
1177 1: varint 1
1178 2: varint 18446744073709551615
1179 raw: 080110ffffffffffffffffff01"#]),
1180 );
1181 assert_eq!(
1182 &encode(Foo {
1183 sint32: -1,
1184 int32: -1,
1185 }),
1186 &[8, 1, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1]
1187 );
1188 }
1189
1190 #[test]
1191 fn test_array() {
1192 assert_field_roundtrips(
1193 [1, 2, 3],
1194 expect!([r#"
1195 1: bytes <020406>
1196 raw: 0a03020406"#]),
1197 );
1198 assert_field_roundtrips(
1199 ["a".to_string(), "b".to_string(), "c".to_string()],
1200 expect!([r#"
1201 1: bytes <0a01610a01620a0163>
1202 raw: 0a090a01610a01620a0163"#]),
1203 );
1204 assert_field_roundtrips(
1205 [vec![1, 2, 3], vec![4, 5, 6]],
1206 expect!([r#"
1207 1: bytes <0a050a030204060a050a03080a0c>
1208 raw: 0a0e0a050a030204060a050a03080a0c"#]),
1209 );
1210 assert_field_roundtrips(
1211 [vec![1u8, 2]],
1212 expect!([r#"
1213 1: bytes <0a020102>
1214 raw: 0a040a020102"#]),
1215 );
1216 assert_field_roundtrips(
1217 [[0_u8, 1], [2, 3]],
1218 expect!([r#"
1219 1: bytes <0a0200010a020203>
1220 raw: 0a080a0200010a020203"#]),
1221 );
1222 assert_field_roundtrips(
1223 [Vec::<()>::new()],
1224 expect!([r#"
1225 1: bytes <0a00>
1226 raw: 0a020a00"#]),
1227 );
1228 assert_field_roundtrips(
1229 [vec!["abc".to_string()]],
1230 expect!([r#"
1231 1: bytes <0a050a03616263>
1232 raw: 0a070a050a03616263"#]),
1233 );
1234 }
1235
1236 #[test]
1237 fn test_nested() {
1238 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
1239 struct Nested<T> {
1240 pub n: u32,
1241 pub foo: T,
1242 }
1243
1244 #[derive(Protobuf, Debug, Clone, PartialEq, Eq)]
1245 struct Foo {
1246 x: u32,
1247 y: u32,
1248 z: String,
1249 w: Option<bool>,
1250 }
1251
1252 let t = Nested {
1253 n: 5,
1254 foo: Foo {
1255 x: 5,
1256 y: 104824,
1257 z: "alphabet".to_owned(),
1258 w: None,
1259 },
1260 };
1261 let t2: Nested<SerializedMessage> = SerializedMessage::from_message(t.clone())
1262 .into_message()
1263 .unwrap();
1264 let t3: Nested<Foo> = SerializedMessage::from_message(t2).into_message().unwrap();
1265 assert_eq!(t, t3);
1266 }
1267
1268 #[test]
1269 fn test_lifetime() {
1270 #[derive(Protobuf)]
1271 struct Foo<'a>(&'a str);
1272
1273 let s = String::from("foo");
1274 let v = encode(Foo(&s));
1275 let foo: Foo<'_> = decode(&v).unwrap();
1276 assert_eq!(foo.0, &s);
1277 }
1278
1279 #[test]
1280 fn test_generic_lifetime() {
1281 #[derive(Protobuf)]
1282 struct Foo<T>(T);
1283
1284 let s = String::from("foo");
1285 let v = encode(Foo(s.as_str()));
1286 let foo: Foo<&str> = decode(&v).unwrap();
1287 assert_eq!(foo.0, &s);
1288 }
1289
1290 #[test]
1291 fn test_infallible() {
1292 assert!(matches!(
1293 decode::<Infallible>(&[])
1294 .unwrap_err()
1295 .source()
1296 .unwrap()
1297 .downcast_ref::<DecodeError>(),
1298 Some(DecodeError::Unexpected)
1299 ));
1300 }
1301
1302 #[test]
1303 fn test_empty_message() {
1304 #[derive(Protobuf)]
1305 struct Message(u32);
1306
1307 let v = encode(((Message(0),),));
1308 assert_eq!(&v, b"");
1309
1310 let _message: ((Message,),) = decode(&[]).unwrap();
1311 }
1312
1313 #[test]
1314 fn test_nested_empty_message() {
1315 #[derive(Debug, Clone, PartialEq, Eq, Protobuf)]
1316 struct Message(Outer, Inner);
1317
1318 #[derive(Debug, Default, Clone, PartialEq, Eq, Protobuf)]
1319 struct Outer(Inner);
1320
1321 #[derive(Debug, Default, Clone, PartialEq, Eq, Protobuf)]
1322 struct Inner(u32);
1323
1324 assert_roundtrips(
1325 Message(Default::default(), Inner(1)),
1326 expect!([r#"
1327 2: bytes <0801>
1328 raw: 12020801"#]),
1329 );
1330 }
1331
1332 #[test]
1333 fn test_transparent_message() {
1334 #[derive(Protobuf, Copy, Clone, PartialEq, Eq, Debug)]
1335 struct Inner(u32);
1336
1337 #[derive(Protobuf, Copy, Clone, PartialEq, Eq, Debug)]
1338 #[mesh(transparent)]
1339 struct TupleStruct(Inner);
1340
1341 #[derive(Protobuf, Copy, Clone, PartialEq, Eq, Debug)]
1342 #[mesh(transparent)]
1343 struct NamedStruct {
1344 x: Inner,
1345 }
1346
1347 #[derive(Protobuf, Copy, Clone, PartialEq, Eq, Debug)]
1348 #[mesh(transparent)]
1349 struct GenericStruct<T>(T);
1350
1351 assert_roundtrips(
1352 TupleStruct(Inner(5)),
1353 expect!([r#"
1354 1: varint 5
1355 raw: 0805"#]),
1356 );
1357 assert_eq!(encode(TupleStruct(Inner(5))), encode(Inner(5)));
1358 assert_eq!(encode(NamedStruct { x: Inner(5) }), encode(Inner(5)));
1359 assert_eq!(encode(GenericStruct(Inner(5))), encode(Inner(5)));
1360 }
1361
1362 #[test]
1363 fn test_transparent_field() {
1364 #[derive(Protobuf, Copy, Clone, PartialEq, Eq, Debug)]
1365 #[mesh(transparent)]
1366 struct Inner(u32);
1367
1368 #[derive(Protobuf, Copy, Clone, PartialEq, Eq, Debug)]
1369 struct Outer<T>(T);
1370
1371 assert_roundtrips(
1372 Outer(Inner(5)),
1373 expect!([r#"
1374 1: varint 5
1375 raw: 0805"#]),
1376 );
1377 assert_eq!(encode(Outer(Inner(5))), encode(Outer(5u32)));
1378 }
1379
1380 #[test]
1381 fn test_transparent_enum() {
1382 #[derive(Protobuf, Clone, PartialEq, Eq, Debug)]
1383 enum Foo {
1384 #[mesh(transparent)]
1385 Bar(u32),
1386 #[mesh(transparent)]
1387 Option(Option<u32>),
1388 #[mesh(transparent)]
1389 Vec(Vec<u32>),
1390 #[mesh(transparent)]
1391 VecNoPack(Vec<(u32,)>),
1392 }
1393
1394 assert_roundtrips(
1395 Foo::Bar(0),
1396 expect!([r#"
1397 1: varint 0
1398 raw: 0800"#]),
1399 );
1400 assert_eq!(encode(Foo::Bar(0)), encode((Some(0),)));
1401 assert_roundtrips(
1402 Foo::Option(Some(5)),
1403 expect!([r#"
1404 2: bytes <0805>
1405 raw: 12020805"#]),
1406 );
1407 assert_roundtrips(
1408 Foo::Option(None),
1409 expect!([r#"
1410 2: bytes <>
1411 raw: 1200"#]),
1412 );
1413 assert_roundtrips(
1414 Foo::Vec(vec![]),
1415 expect!([r#"
1416 3: bytes <>
1417 raw: 1a00"#]),
1418 );
1419 assert_roundtrips(
1420 Foo::Vec(vec![5]),
1421 expect!([r#"
1422 3: bytes <0a0105>
1423 raw: 1a030a0105"#]),
1424 );
1425 assert_roundtrips(
1426 Foo::VecNoPack(vec![(5,)]),
1427 expect!([r#"
1428 4: bytes <0a020805>
1429 raw: 22040a020805"#]),
1430 );
1431 }
1432
1433 #[test]
1434 fn test_cow() {
1435 #[derive(Protobuf)]
1436 struct OwnedString<'a>(#[mesh(encoding = "OwningCowField")] Cow<'a, str>);
1437 #[derive(Protobuf)]
1438 struct BorrowedString<'a>(#[mesh(encoding = "BorrowedCowField")] Cow<'a, str>);
1439 #[derive(Protobuf)]
1440 struct OwnedBytes<'a>(#[mesh(encoding = "OwningCowField")] Cow<'a, [u8]>);
1441 #[derive(Protobuf)]
1442 struct BorrowedBytes<'a>(#[mesh(encoding = "BorrowedCowField")] Cow<'a, [u8]>);
1443
1444 let s_owning: OwnedString<'_>;
1445 let v_owning: OwnedBytes<'_>;
1446
1447 {
1448 let b = encode(("abc",));
1449 let mut b2 = b.clone();
1450 b2.extend(encode(("def",)));
1451
1452 let s_borrowed: BorrowedString<'_>;
1453 let v_borrowed: BorrowedBytes<'_>;
1454 let v_borrowed2: BorrowedBytes<'_>;
1455 {
1456 let (s,): (String,) = decode(&b2).unwrap();
1457 assert_eq!(&s, "def");
1458 let (v,): (Vec<u8>,) = decode(&b2).unwrap();
1459 assert_eq!(&v, b"abcdef");
1460
1461 s_owning = decode(&b2).unwrap();
1462 let s_owning = s_owning.0;
1463 assert!(matches!(s_owning, Cow::Owned(_)));
1464 assert_eq!(s_owning.as_ref(), "def");
1465
1466 s_borrowed = decode(&b2).unwrap();
1467 let s_borrowed = s_borrowed.0;
1468 assert!(matches!(s_borrowed, Cow::Borrowed(_)));
1469 assert_eq!(s_borrowed.as_ref(), "def");
1470
1471 v_owning = decode(&b2).unwrap();
1472 let v_owning = v_owning.0;
1473 assert!(matches!(v_owning, Cow::Owned(_)));
1474 assert_eq!(v_owning.as_ref(), b"abcdef");
1475
1476 v_borrowed = decode(&b).unwrap();
1477 let v_borrowed = v_borrowed.0;
1478 assert!(matches!(v_borrowed, Cow::Borrowed(_)));
1479 assert_eq!(v_borrowed.as_ref(), b"abc");
1480
1481 v_borrowed2 = decode(&b2).unwrap();
1483 let v_borrowed2 = v_borrowed2.0;
1484 assert!(matches!(v_borrowed2, Cow::Owned(_)));
1485 assert_eq!(v_borrowed2.as_ref(), b"abcdef");
1486 }
1487 }
1488 }
1489
1490 #[test]
1491 fn test_duration() {
1492 assert_roundtrips(
1493 Duration::ZERO,
1494 expect!([r#"
1495 empty
1496 raw: "#]),
1497 );
1498 assert_roundtrips(
1499 Duration::from_secs(1),
1500 expect!([r#"
1501 1: varint 1
1502 raw: 0801"#]),
1503 );
1504 assert_roundtrips(
1505 Duration::from_secs(1) + Duration::from_nanos(10000),
1506 expect!([r#"
1507 1: varint 1
1508 2: varint 10000
1509 raw: 080110904e"#]),
1510 );
1511 assert_roundtrips(
1512 Duration::from_secs(1) - Duration::from_nanos(10000),
1513 expect!([r#"
1514 2: varint 999990000
1515 raw: 10f0c5eadc03"#]),
1516 );
1517 decode::<Duration>(&encode((-1i64 as u64, 0u32))).unwrap_err();
1518 assert_eq!(
1519 decode::<Duration>(&encode((1u64, 1u32))).unwrap(),
1520 Duration::from_secs(1) + Duration::from_nanos(1)
1521 );
1522 }
1523
1524 #[test]
1525 fn test_failure_recovery() {
1526 let m = encode(("foo", 2, 3));
1527 decode::<(String, String, String)>(&m).unwrap_err();
1528 }
1529}