mesh_protobuf/
encoding.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Protobuf encodings for Rust types.
5
6pub use super::time::DurationEncoding;
7
8use super::CopyExtend;
9use super::DecodeError;
10use super::DefaultEncoding;
11use super::FieldDecode;
12use super::FieldEncode;
13use super::InplaceOption;
14use super::MaybeUninit;
15use super::MessageDecode;
16use super::MessageEncode;
17use super::PackedDecode;
18use super::PackedEncode;
19use super::Result;
20use super::ResultExt;
21use super::SerializedMessage;
22use super::Wrapping;
23use super::inplace_some;
24use super::protobuf::FieldReader;
25use super::protobuf::FieldSizer;
26use super::protobuf::FieldWriter;
27use super::protobuf::MessageReader;
28use super::protobuf::MessageSizer;
29use super::protobuf::MessageWriter;
30use super::protobuf::PackedReader;
31use super::protobuf::PackedSizer;
32use super::protobuf::PackedWriter;
33use super::protobuf::decode_with;
34use crate::Error;
35use crate::inplace_none;
36use crate::protobuf::WireType;
37use crate::protofile::DescribeField;
38use crate::protofile::DescribeMessage;
39use crate::protofile::FieldType;
40use crate::protofile::MessageDescription;
41use alloc::borrow::Cow;
42use alloc::boxed::Box;
43use alloc::collections::BTreeMap;
44use alloc::string::String;
45use alloc::sync::Arc;
46use alloc::vec::Vec;
47use core::convert::Infallible;
48use core::marker::PhantomData;
49use core::num::NonZeroI8;
50use core::num::NonZeroI16;
51use core::num::NonZeroI32;
52use core::num::NonZeroI64;
53use core::num::NonZeroIsize;
54use core::num::NonZeroU8;
55use core::num::NonZeroU16;
56use core::num::NonZeroU32;
57use core::num::NonZeroU64;
58use core::num::NonZeroUsize;
59use core::time::Duration;
60use thiserror::Error;
61use zerocopy::Immutable;
62use zerocopy::KnownLayout;
63
64/// An encoding derived by `mesh_derive` for `T`.
65#[derive(Copy, Clone)]
66pub struct DerivedEncoding<T>(PhantomData<fn(T) -> T>);
67
68/// A field encoding for message encoding implementations.
69///
70/// Writes the message as a protobuf message field.
71pub struct MessageEncoding<E>(E);
72
73impl<E: DescribeMessage<T>, T> DescribeField<T> for MessageEncoding<E> {
74    const FIELD_TYPE: FieldType<'static> = FieldType::message(|| E::DESCRIPTION);
75}
76
77impl<E: DescribeMessage<T>, T> DescribeMessage<T> for MessageEncoding<E> {
78    const DESCRIPTION: MessageDescription<'static> = E::DESCRIPTION;
79}
80
81impl<T, R, E: MessageEncode<T, R>> MessageEncode<T, R> for MessageEncoding<E> {
82    fn write_message(item: T, writer: MessageWriter<'_, '_, R>) {
83        E::write_message(item, writer)
84    }
85
86    fn compute_message_size(item: &mut T, sizer: MessageSizer<'_>) {
87        E::compute_message_size(item, sizer)
88    }
89}
90
91impl<'a, T, R, E: MessageDecode<'a, T, R>> MessageDecode<'a, T, R> for MessageEncoding<E> {
92    fn read_message(
93        item: &mut InplaceOption<'_, T>,
94        reader: MessageReader<'a, '_, R>,
95    ) -> Result<()> {
96        E::read_message(item, reader)
97    }
98}
99
100impl<T, R, E: MessageEncode<T, R>> FieldEncode<T, R> for MessageEncoding<E> {
101    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
102        writer.message(|message| E::write_message(item, message));
103    }
104
105    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
106        sizer.message(|message| E::compute_message_size(item, message));
107    }
108}
109
110impl<'a, T, R, E: MessageDecode<'a, T, R>> FieldDecode<'a, T, R> for MessageEncoding<E> {
111    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
112        E::read_message(item, reader.message().typed::<Self>()?)
113    }
114
115    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
116        // Decode using an empty message.
117        decode_with::<E, _, _>(item, &[], &mut [])
118    }
119}
120
121/// A trait for converting a value to a u64 for use in varint encodings.
122pub trait ToNumber: Copy {
123    /// Convert to a `u64`.
124    fn to_u64(self) -> u64;
125    /// Convert to an `i64`.
126    fn to_i64(self) -> i64;
127}
128
129impl<T: ToNumber> ToNumber for &T {
130    fn to_u64(self) -> u64 {
131        (*self).to_u64()
132    }
133
134    fn to_i64(self) -> i64 {
135        (*self).to_i64()
136    }
137}
138
139/// A trait for converting a value to from u64 for use in varint encodings.
140///
141/// N.B. The protobuf behavior is to truncate integers rather than fail on
142/// overflow.
143pub trait FromNumber: Copy {
144    /// Convert from an `i64`.
145    fn from_i64(v: i64) -> Result<Self>;
146    /// Convert from a `u64`.
147    fn from_u64(v: u64) -> Result<Self>;
148}
149
150macro_rules! number {
151    ($($ty:ty)*) => {
152        $(
153        impl ToNumber for $ty {
154            fn to_u64(self) -> u64 {
155                self as u64
156            }
157            fn to_i64(self) -> i64 {
158                self as i64
159            }
160        }
161
162        impl FromNumber for $ty {
163            fn from_u64(v: u64) -> Result<Self> {
164                Ok(v as Self)
165            }
166            fn from_i64(v: i64) -> Result<Self> {
167                Ok(v as Self)
168            }
169        }
170        )*
171    };
172}
173
174number!(usize u64 u32 u16 u8 isize i64 i32 i16 i8);
175
176#[derive(Debug, Error)]
177#[error("value must be non-zero")]
178struct MustBeNonZero;
179
180macro_rules! nonzero_number {
181    ($($ty:ty)*) => {
182        $(
183        impl ToNumber for $ty {
184            fn to_u64(self) -> u64 {
185                self.get() as u64
186            }
187            fn to_i64(self) -> i64 {
188                self.get() as i64
189            }
190        }
191
192        impl FromNumber for $ty {
193            fn from_u64(v: u64) -> Result<Self> {
194                Self::new(v as _).ok_or(Error::new(MustBeNonZero))
195            }
196            fn from_i64(v: i64) -> Result<Self> {
197                Self::new(v as _).ok_or(Error::new(MustBeNonZero))
198            }
199        }
200        )*
201    };
202}
203
204nonzero_number!(NonZeroUsize NonZeroU64 NonZeroU32 NonZeroU16 NonZeroU8 NonZeroIsize NonZeroI64 NonZeroI32 NonZeroI16 NonZeroI8);
205
206impl<T: ToNumber> ToNumber for Wrapping<T> {
207    fn to_u64(self) -> u64 {
208        self.0.to_u64()
209    }
210
211    fn to_i64(self) -> i64 {
212        self.0.to_i64()
213    }
214}
215
216impl<T: FromNumber> FromNumber for Wrapping<T> {
217    fn from_u64(v: u64) -> Result<Self> {
218        Ok(Self(T::from_u64(v)?))
219    }
220
221    fn from_i64(v: i64) -> Result<Self> {
222        Ok(Self(T::from_i64(v)?))
223    }
224}
225
226impl ToNumber for bool {
227    fn to_u64(self) -> u64 {
228        self as u64
229    }
230
231    fn to_i64(self) -> i64 {
232        self as i64
233    }
234}
235
236impl FromNumber for bool {
237    fn from_u64(v: u64) -> Result<Self> {
238        Ok(v != 0)
239    }
240
241    fn from_i64(v: i64) -> Result<Self> {
242        Ok(v != 0)
243    }
244}
245
246impl ToNumber for char {
247    fn to_u64(self) -> u64 {
248        self as u64
249    }
250
251    fn to_i64(self) -> i64 {
252        self as i64
253    }
254}
255
256impl FromNumber for char {
257    fn from_u64(v: u64) -> Result<Self> {
258        v.try_into()
259            .ok()
260            .and_then(core::char::from_u32)
261            .ok_or_else(|| DecodeError::InvalidUtf32.into())
262    }
263
264    fn from_i64(v: i64) -> Result<Self> {
265        Self::from_u64(v as u64)
266    }
267}
268
269/// A `FixedNumber` can be converted to a u32 or u64 type for use with fixed64
270/// and fixed32 fields.
271pub trait FixedNumber: Copy {
272    /// The target type, `u32` or `u64`.
273    type Type;
274    /// Converts to the fixed type.
275    fn to_fixed(self) -> Self::Type;
276    /// Converts from the fixed type.
277    fn from_fixed(_: Self::Type) -> Self;
278}
279
280impl FixedNumber for u32 {
281    type Type = u32;
282    fn to_fixed(self) -> u32 {
283        self
284    }
285
286    fn from_fixed(v: u32) -> Self {
287        v
288    }
289}
290
291impl FixedNumber for i32 {
292    type Type = u32;
293    fn to_fixed(self) -> u32 {
294        self as u32
295    }
296
297    fn from_fixed(v: u32) -> Self {
298        v as Self
299    }
300}
301
302impl FixedNumber for f32 {
303    type Type = u32;
304    fn to_fixed(self) -> u32 {
305        self.to_bits()
306    }
307
308    fn from_fixed(v: u32) -> Self {
309        Self::from_bits(v)
310    }
311}
312
313impl FixedNumber for u64 {
314    type Type = u64;
315    fn to_fixed(self) -> u64 {
316        self
317    }
318
319    fn from_fixed(v: u64) -> Self {
320        v
321    }
322}
323
324impl FixedNumber for i64 {
325    type Type = u64;
326    fn to_fixed(self) -> u64 {
327        self as u64
328    }
329
330    fn from_fixed(v: u64) -> Self {
331        v as Self
332    }
333}
334
335impl FixedNumber for f64 {
336    type Type = u64;
337    fn to_fixed(self) -> u64 {
338        self.to_bits()
339    }
340
341    fn from_fixed(v: u64) -> Self {
342        Self::from_bits(v)
343    }
344}
345
346// This encodes the address as a u32, with the first octet in the high 8 bits of
347// the u32 and so on.
348//
349// In particular, this is not byte swapped to network byte order on
350// little-endian platforms, as you might naively expect, since this would result
351// in a different wire format across different architectures.
352impl FixedNumber for core::net::Ipv4Addr {
353    type Type = u32;
354
355    fn to_fixed(self) -> u32 {
356        self.into()
357    }
358
359    fn from_fixed(v: u32) -> Self {
360        v.into()
361    }
362}
363
364macro_rules! builtin_field_type {
365    ($ty:ty, $encoding:ty, $name:expr) => {
366        impl DescribeField<$ty> for $encoding {
367            const FIELD_TYPE: FieldType<'static> = FieldType::builtin($name);
368        }
369    };
370}
371
372/// A field encoder for fixed64 fields.
373pub struct Fixed64Field;
374
375builtin_field_type!(u64, Fixed64Field, "fixed64");
376builtin_field_type!(i64, Fixed64Field, "sfixed64");
377builtin_field_type!(f64, Fixed64Field, "double");
378
379impl<T: FixedNumber<Type = u64>, R> FieldEncode<T, R> for Fixed64Field {
380    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
381        writer.fixed64(item.to_fixed());
382    }
383
384    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
385        sizer.fixed64(item.to_fixed());
386    }
387
388    fn packed<'a>() -> Option<&'a dyn PackedEncode<T>>
389    where
390        T: 'a,
391    {
392        Some(&Self)
393    }
394}
395
396impl<T: FixedNumber<Type = u64>> PackedEncode<T> for Fixed64Field {
397    fn write_packed(&self, data: &[T], mut writer: PackedWriter<'_, '_>) {
398        for v in data {
399            writer.fixed64(v.to_fixed());
400        }
401    }
402
403    fn compute_packed_size(&self, data: &[T], mut sizer: PackedSizer<'_>) {
404        for _ in data {
405            sizer.fixed64();
406        }
407    }
408
409    fn must_pack(&self) -> bool {
410        false
411    }
412}
413
414impl<'a, T: FixedNumber<Type = u64>, R> FieldDecode<'a, T, R> for Fixed64Field {
415    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
416        item.set(T::from_fixed(reader.fixed64()?));
417        Ok(())
418    }
419
420    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
421        item.set(T::from_fixed(0));
422        Ok(())
423    }
424
425    fn packed<'p, C: CopyExtend<T>>() -> Option<&'p dyn PackedDecode<'a, T, C>>
426    where
427        T: 'p,
428    {
429        Some(&Self)
430    }
431}
432
433impl<T: FixedNumber<Type = u64>, C: CopyExtend<T>> PackedDecode<'_, T, C> for Fixed64Field {
434    fn read_packed(&self, data: &mut C, reader: &mut PackedReader<'_>) -> Result<()> {
435        while let Some(v) = reader.fixed64()? {
436            data.push(T::from_fixed(v));
437        }
438        Ok(())
439    }
440
441    fn must_pack(&self) -> bool {
442        false
443    }
444}
445
446/// A field encoder for fixed32 fields.
447pub struct Fixed32Field;
448
449builtin_field_type!(u32, Fixed32Field, "fixed32");
450builtin_field_type!(i32, Fixed32Field, "sfixed32");
451builtin_field_type!(f32, Fixed32Field, "float");
452
453builtin_field_type!(core::net::Ipv4Addr, Fixed32Field, "fixed32");
454
455impl<T: FixedNumber<Type = u32>, R> FieldEncode<T, R> for Fixed32Field {
456    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
457        writer.fixed32(item.to_fixed());
458    }
459
460    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
461        sizer.fixed32(item.to_fixed());
462    }
463
464    fn packed<'a>() -> Option<&'a dyn PackedEncode<T>>
465    where
466        T: 'a,
467    {
468        Some(&Self)
469    }
470}
471
472impl<T: FixedNumber<Type = u32>> PackedEncode<T> for Fixed32Field {
473    fn write_packed(&self, data: &[T], mut writer: PackedWriter<'_, '_>) {
474        for v in data {
475            writer.fixed32(v.to_fixed());
476        }
477    }
478
479    fn compute_packed_size(&self, data: &[T], mut sizer: PackedSizer<'_>) {
480        for _ in data {
481            sizer.fixed32();
482        }
483    }
484
485    fn must_pack(&self) -> bool {
486        false
487    }
488}
489
490impl<'a, T: FixedNumber<Type = u32>, R> FieldDecode<'a, T, R> for Fixed32Field {
491    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
492        item.set(T::from_fixed(reader.fixed32()?));
493        Ok(())
494    }
495
496    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
497        item.set(T::from_fixed(0));
498        Ok(())
499    }
500
501    fn packed<'p, C: CopyExtend<T>>() -> Option<&'p dyn PackedDecode<'a, T, C>>
502    where
503        T: 'p,
504    {
505        Some(&Self)
506    }
507}
508
509impl<T: FixedNumber<Type = u32>, C: CopyExtend<T>> PackedDecode<'_, T, C> for Fixed32Field {
510    fn read_packed(&self, data: &mut C, reader: &mut PackedReader<'_>) -> Result<()> {
511        while let Some(v) = reader.fixed32()? {
512            data.push(T::from_fixed(v));
513        }
514        Ok(())
515    }
516
517    fn must_pack(&self) -> bool {
518        false
519    }
520}
521
522/// A field encoder for u8.
523///
524/// This is separate from VarintField so that the packed format can be a byte
525/// array instead of a varint array.
526pub struct ByteField;
527
528impl DescribeField<u8> for ByteField {
529    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("uint32");
530    const PACKED_TYPE: Option<&'static str> = Some("bytes");
531}
532
533impl<R> FieldEncode<u8, R> for ByteField {
534    fn write_field(item: u8, writer: FieldWriter<'_, '_, R>) {
535        writer.varint(item.into())
536    }
537
538    fn compute_field_size(item: &mut u8, sizer: FieldSizer<'_>) {
539        sizer.varint((*item).into())
540    }
541
542    fn packed<'a>() -> Option<&'a dyn PackedEncode<u8>> {
543        Some(&Self)
544    }
545}
546
547impl PackedEncode<u8> for ByteField {
548    fn write_packed(&self, data: &[u8], mut writer: PackedWriter<'_, '_>) {
549        writer.bytes(data);
550    }
551
552    fn compute_packed_size(&self, data: &[u8], mut sizer: PackedSizer<'_>) {
553        sizer.bytes(data.len());
554    }
555
556    fn must_pack(&self) -> bool {
557        true
558    }
559}
560
561impl<'a, R> FieldDecode<'a, u8, R> for ByteField {
562    fn read_field(item: &mut InplaceOption<'_, u8>, reader: FieldReader<'_, '_, R>) -> Result<()> {
563        item.set(reader.varint()? as u8);
564        Ok(())
565    }
566
567    fn default_field(item: &mut InplaceOption<'_, u8>) -> Result<()> {
568        item.set(0);
569        Ok(())
570    }
571
572    fn packed<'p, C: CopyExtend<u8>>() -> Option<&'p dyn PackedDecode<'a, u8, C>>
573    where
574        u8: 'p,
575    {
576        Some(&Self)
577    }
578}
579
580impl<C: CopyExtend<u8>> PackedDecode<'_, u8, C> for ByteField {
581    fn read_packed(&self, data: &mut C, reader: &mut PackedReader<'_>) -> Result<()> {
582        data.extend_from_slice(reader.bytes());
583        Ok(())
584    }
585
586    fn must_pack(&self) -> bool {
587        true
588    }
589}
590
591/// A field encoder for varint fields.
592pub struct VarintField;
593
594builtin_field_type!(u64, VarintField, "uint64");
595builtin_field_type!(u32, VarintField, "uint32");
596builtin_field_type!(u16, VarintField, "uint32");
597builtin_field_type!(u8, VarintField, "uint32");
598builtin_field_type!(usize, VarintField, "uint64");
599builtin_field_type!(i64, VarintField, "int64");
600builtin_field_type!(i32, VarintField, "int32");
601builtin_field_type!(i16, VarintField, "int32");
602builtin_field_type!(i8, VarintField, "int32");
603builtin_field_type!(isize, VarintField, "int64");
604builtin_field_type!(bool, VarintField, "bool");
605builtin_field_type!(NonZeroU64, VarintField, "uint64");
606builtin_field_type!(NonZeroU32, VarintField, "uint32");
607builtin_field_type!(NonZeroU16, VarintField, "uint32");
608builtin_field_type!(NonZeroU8, VarintField, "uint32");
609builtin_field_type!(NonZeroUsize, VarintField, "uint64");
610builtin_field_type!(NonZeroI64, VarintField, "int64");
611builtin_field_type!(NonZeroI32, VarintField, "int32");
612builtin_field_type!(NonZeroI16, VarintField, "int32");
613builtin_field_type!(NonZeroI8, VarintField, "int32");
614builtin_field_type!(NonZeroIsize, VarintField, "int64");
615
616impl<T: ToNumber, R> FieldEncode<T, R> for VarintField {
617    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
618        writer.varint(item.to_u64())
619    }
620
621    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
622        sizer.varint(item.to_u64())
623    }
624
625    fn packed<'a>() -> Option<&'a dyn PackedEncode<T>>
626    where
627        T: 'a,
628    {
629        Some(&Self)
630    }
631}
632
633impl<T: ToNumber> PackedEncode<T> for VarintField {
634    fn write_packed(&self, data: &[T], mut writer: PackedWriter<'_, '_>) {
635        for v in data {
636            writer.varint(v.to_u64());
637        }
638    }
639
640    fn compute_packed_size(&self, data: &[T], mut sizer: PackedSizer<'_>) {
641        for v in data {
642            sizer.varint(v.to_u64());
643        }
644    }
645
646    fn must_pack(&self) -> bool {
647        false
648    }
649}
650
651impl<'a, T: FromNumber, R> FieldDecode<'a, T, R> for VarintField {
652    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
653        item.set(T::from_u64(reader.varint()?)?);
654        Ok(())
655    }
656
657    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
658        item.set(T::from_u64(0)?);
659        Ok(())
660    }
661
662    fn packed<'p, C: CopyExtend<T>>() -> Option<&'p dyn PackedDecode<'a, T, C>>
663    where
664        T: 'p,
665    {
666        Some(&Self)
667    }
668}
669
670impl<T: FromNumber, C: CopyExtend<T>> PackedDecode<'_, T, C> for VarintField {
671    fn read_packed(&self, data: &mut C, reader: &mut PackedReader<'_>) -> Result<()> {
672        while let Some(v) = reader.varint()? {
673            data.push(T::from_u64(v)?);
674        }
675        Ok(())
676    }
677
678    fn must_pack(&self) -> bool {
679        false
680    }
681}
682
683/// A field encoder for signed (zigzag encoded) varint fields.
684///
685/// This is used for protobuf sint32, etc. fields and not for int32, etc.
686pub struct SignedVarintField;
687
688builtin_field_type!(i64, SignedVarintField, "sint64");
689builtin_field_type!(i32, SignedVarintField, "sint32");
690builtin_field_type!(i16, SignedVarintField, "sint32");
691builtin_field_type!(i8, SignedVarintField, "sint32");
692builtin_field_type!(isize, SignedVarintField, "sint64");
693builtin_field_type!(NonZeroI64, SignedVarintField, "sint64");
694builtin_field_type!(NonZeroI32, SignedVarintField, "sint32");
695builtin_field_type!(NonZeroI16, SignedVarintField, "sint32");
696builtin_field_type!(NonZeroI8, SignedVarintField, "sint32");
697builtin_field_type!(NonZeroIsize, SignedVarintField, "sint64");
698
699impl<T: ToNumber, R> FieldEncode<T, R> for SignedVarintField {
700    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
701        writer.svarint(item.to_i64())
702    }
703
704    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
705        sizer.svarint(item.to_i64())
706    }
707
708    fn packed<'a>() -> Option<&'a dyn PackedEncode<T>>
709    where
710        T: 'a,
711    {
712        Some(&Self)
713    }
714}
715
716impl<T: ToNumber> PackedEncode<T> for SignedVarintField {
717    fn write_packed(&self, data: &[T], mut writer: PackedWriter<'_, '_>) {
718        for v in data {
719            writer.svarint(v.to_i64());
720        }
721    }
722
723    fn compute_packed_size(&self, data: &[T], mut sizer: PackedSizer<'_>) {
724        for v in data {
725            sizer.svarint(v.to_i64());
726        }
727    }
728
729    fn must_pack(&self) -> bool {
730        false
731    }
732}
733
734impl<'a, T: FromNumber, R> FieldDecode<'a, T, R> for SignedVarintField {
735    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
736        item.set(T::from_i64(reader.svarint()?)?);
737        Ok(())
738    }
739
740    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
741        item.set(T::from_i64(0)?);
742        Ok(())
743    }
744
745    fn packed<'p, C: CopyExtend<T>>() -> Option<&'p dyn PackedDecode<'a, T, C>>
746    where
747        T: 'p,
748    {
749        Some(&Self)
750    }
751}
752
753impl<T: FromNumber, C: CopyExtend<T>> PackedDecode<'_, T, C> for SignedVarintField {
754    fn read_packed(&self, data: &mut C, reader: &mut PackedReader<'_>) -> Result<()> {
755        while let Some(v) = reader.svarint()? {
756            data.push(T::from_i64(v)?);
757        }
758        Ok(())
759    }
760
761    fn must_pack(&self) -> bool {
762        false
763    }
764}
765
766/// A field encoder for u128.
767///
768/// Writes the value as a little-endian-encoded 16-byte byte array.
769pub struct U128LittleEndianField;
770
771builtin_field_type!(u128, U128LittleEndianField, "bytes");
772
773impl<T: Copy + Into<u128>, R> FieldEncode<T, R> for U128LittleEndianField {
774    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
775        let item = item.into();
776        if item != 0 || writer.write_empty() {
777            writer.bytes(&item.to_le_bytes());
778        }
779    }
780
781    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
782        let item = (*item).into();
783        if item != 0 || sizer.write_empty() {
784            sizer.bytes(16);
785        }
786    }
787}
788
789impl<T: From<u128>, R> FieldDecode<'_, T, R> for U128LittleEndianField {
790    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
791        item.set(
792            u128::from_le_bytes(
793                reader
794                    .bytes()?
795                    .try_into()
796                    .map_err(|_| DecodeError::BadU128)?,
797            )
798            .into(),
799        );
800        Ok(())
801    }
802
803    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
804        item.set(0.into());
805        Ok(())
806    }
807}
808
809/// A field encoder for an IPv6 address.
810///
811/// Writes the value in octet order as a 16-byte array.
812pub struct Ipv6AddrField;
813
814builtin_field_type!(core::net::Ipv6Addr, Ipv6AddrField, "bytes");
815
816impl<R> FieldEncode<core::net::Ipv6Addr, R> for Ipv6AddrField {
817    fn write_field(item: core::net::Ipv6Addr, writer: FieldWriter<'_, '_, R>) {
818        if !item.is_unspecified() || writer.write_empty() {
819            writer.bytes(&item.octets());
820        }
821    }
822
823    fn compute_field_size(item: &mut core::net::Ipv6Addr, sizer: FieldSizer<'_>) {
824        if !item.is_unspecified() || sizer.write_empty() {
825            sizer.bytes(16);
826        }
827    }
828}
829
830impl<R> FieldDecode<'_, core::net::Ipv6Addr, R> for Ipv6AddrField {
831    fn read_field(
832        item: &mut InplaceOption<'_, core::net::Ipv6Addr>,
833        reader: FieldReader<'_, '_, R>,
834    ) -> Result<()> {
835        let v: [u8; 16] = reader
836            .bytes()?
837            .try_into()
838            .map_err(|_| DecodeError::BadIpv6)?;
839
840        item.set(v.into());
841        Ok(())
842    }
843
844    fn default_field(item: &mut InplaceOption<'_, core::net::Ipv6Addr>) -> Result<()> {
845        item.set(core::net::Ipv6Addr::UNSPECIFIED);
846        Ok(())
847    }
848}
849
850/// A field encoder for byte streams.
851pub struct BytesField;
852
853impl<T: AsRef<[u8]>> DescribeField<T> for BytesField {
854    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("bytes");
855}
856
857impl<T: AsRef<[u8]>, R> FieldEncode<T, R> for BytesField {
858    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
859        writer.bytes(item.as_ref())
860    }
861
862    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
863        sizer.bytes(item.as_ref().len())
864    }
865}
866
867impl<'a, T: From<&'a [u8]> + Default, R> FieldDecode<'a, T, R> for BytesField {
868    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
869        item.set(reader.bytes()?.into());
870        Ok(())
871    }
872
873    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
874        item.set(Default::default());
875        Ok(())
876    }
877}
878
879/// A field encoder for strings.
880pub struct StringField;
881
882impl<T: AsRef<str>> DescribeField<T> for StringField {
883    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("string");
884}
885
886impl<T: AsRef<str>, R> FieldEncode<T, R> for StringField {
887    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
888        writer.bytes(item.as_ref().as_bytes())
889    }
890
891    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
892        sizer.bytes(item.as_ref().len())
893    }
894}
895
896impl<'a, T: From<&'a str> + Default, R> FieldDecode<'a, T, R> for StringField {
897    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
898        item.set(
899            core::str::from_utf8(reader.bytes()?)
900                .map_err(DecodeError::InvalidUtf8)?
901                .into(),
902        );
903        Ok(())
904    }
905
906    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
907        item.set(Default::default());
908        Ok(())
909    }
910}
911
912/// An encoder for `Cow<'a, str>` or `Cow<'a, [u8]>` that creates
913/// [`Cow::Borrowed`] on read.
914pub struct BorrowedCowField;
915
916impl DescribeField<Cow<'_, str>> for BorrowedCowField {
917    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("string");
918}
919
920impl<'a, R> FieldEncode<Cow<'a, str>, R> for BorrowedCowField {
921    fn write_field(item: Cow<'a, str>, writer: FieldWriter<'_, '_, R>) {
922        writer.bytes(item.as_bytes())
923    }
924
925    fn compute_field_size(item: &mut Cow<'a, str>, sizer: FieldSizer<'_>) {
926        sizer.bytes(item.len())
927    }
928}
929
930impl<'a, R> FieldDecode<'a, Cow<'a, str>, R> for BorrowedCowField {
931    fn read_field(
932        item: &mut InplaceOption<'_, Cow<'a, str>>,
933        reader: FieldReader<'a, '_, R>,
934    ) -> Result<()> {
935        item.set(Cow::Borrowed(
936            core::str::from_utf8(reader.bytes()?).map_err(DecodeError::InvalidUtf8)?,
937        ));
938        Ok(())
939    }
940
941    fn default_field(item: &mut InplaceOption<'_, Cow<'a, str>>) -> Result<()> {
942        item.set(Cow::Borrowed(""));
943        Ok(())
944    }
945}
946
947impl<'a, R> FieldEncode<Cow<'a, [u8]>, R> for BorrowedCowField {
948    fn write_field(item: Cow<'a, [u8]>, writer: FieldWriter<'_, '_, R>) {
949        writer.bytes(item.as_ref())
950    }
951
952    fn compute_field_size(item: &mut Cow<'a, [u8]>, sizer: FieldSizer<'_>) {
953        sizer.bytes(item.len())
954    }
955}
956
957impl<'a, R> FieldDecode<'a, Cow<'a, [u8]>, R> for BorrowedCowField {
958    fn read_field(
959        item: &mut InplaceOption<'_, Cow<'a, [u8]>>,
960        reader: FieldReader<'a, '_, R>,
961    ) -> Result<()> {
962        let bytes = reader.bytes()?;
963        let item = item.get_or_insert(Cow::Borrowed(&[]));
964        if item.is_empty() {
965            *item = Cow::Borrowed(bytes);
966        } else {
967            // Extend the bytes instead of replacing them to behave like protobuf's
968            // bytes fields.
969            item.to_mut().extend_from_slice(bytes);
970        }
971        Ok(())
972    }
973
974    fn default_field(item: &mut InplaceOption<'_, Cow<'a, [u8]>>) -> Result<()> {
975        item.set(Cow::Borrowed(&[]));
976        Ok(())
977    }
978}
979
980/// An encoder for `Cow<'a, str>` or `Cow<'a, [u8]>` that creates [`Cow::Owned`]
981/// on read.
982pub struct OwningCowField;
983
984impl DescribeField<Cow<'_, str>> for OwningCowField {
985    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("string");
986}
987
988impl<'a, R> FieldEncode<Cow<'a, str>, R> for OwningCowField {
989    fn write_field(item: Cow<'a, str>, writer: FieldWriter<'_, '_, R>) {
990        writer.bytes(item.as_bytes())
991    }
992
993    fn compute_field_size(item: &mut Cow<'a, str>, sizer: FieldSizer<'_>) {
994        sizer.bytes(item.len())
995    }
996}
997
998impl<'a, 'b, R> FieldDecode<'a, Cow<'b, str>, R> for OwningCowField {
999    fn read_field(
1000        item: &mut InplaceOption<'_, Cow<'b, str>>,
1001        reader: FieldReader<'a, '_, R>,
1002    ) -> Result<()> {
1003        item.set(Cow::Owned(
1004            core::str::from_utf8(reader.bytes()?)
1005                .map_err(DecodeError::InvalidUtf8)?
1006                .into(),
1007        ));
1008        Ok(())
1009    }
1010
1011    fn default_field(item: &mut InplaceOption<'_, Cow<'b, str>>) -> Result<()> {
1012        item.set(Cow::Borrowed(""));
1013        Ok(())
1014    }
1015}
1016
1017impl<'a, R> FieldEncode<Cow<'a, [u8]>, R> for OwningCowField {
1018    fn write_field(item: Cow<'a, [u8]>, writer: FieldWriter<'_, '_, R>) {
1019        writer.bytes(item.as_ref())
1020    }
1021
1022    fn compute_field_size(item: &mut Cow<'a, [u8]>, sizer: FieldSizer<'_>) {
1023        sizer.bytes(item.len())
1024    }
1025}
1026
1027impl<'a, 'b, R> FieldDecode<'a, Cow<'b, [u8]>, R> for OwningCowField {
1028    fn read_field(
1029        item: &mut InplaceOption<'_, Cow<'b, [u8]>>,
1030        reader: FieldReader<'a, '_, R>,
1031    ) -> Result<()> {
1032        let bytes = reader.bytes()?;
1033        item.get_or_insert(Cow::Borrowed(&[]))
1034            .to_mut()
1035            .extend_from_slice(bytes);
1036        Ok(())
1037    }
1038
1039    fn default_field(item: &mut InplaceOption<'_, Cow<'b, [u8]>>) -> Result<()> {
1040        item.set(Cow::Borrowed(&[]));
1041        Ok(())
1042    }
1043}
1044
1045/// A field encoder for `Option`.
1046pub struct OptionField<E>(E);
1047
1048impl<T, E: DescribeField<T>> DescribeField<Option<T>> for OptionField<E> {
1049    const FIELD_TYPE: FieldType<'static> = {
1050        if E::FIELD_TYPE.is_sequence() {
1051            FieldType::tuple(&[E::FIELD_TYPE]).optional()
1052        } else {
1053            E::FIELD_TYPE.optional()
1054        }
1055    };
1056}
1057
1058impl<T, R, E: FieldEncode<T, R>> FieldEncode<Option<T>, R> for OptionField<E> {
1059    fn write_field(item: Option<T>, writer: FieldWriter<'_, '_, R>) {
1060        if let Some(v) = item {
1061            E::write_field_in_sequence(v, &mut writer.sequence())
1062        }
1063    }
1064
1065    fn compute_field_size(item: &mut Option<T>, sizer: FieldSizer<'_>) {
1066        if let Some(v) = item {
1067            E::compute_field_size_in_sequence(v, &mut sizer.sequence())
1068        }
1069    }
1070
1071    fn wrap_in_sequence() -> bool {
1072        true
1073    }
1074}
1075
1076impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Option<T>, R> for OptionField<E> {
1077    fn read_field(
1078        item: &mut InplaceOption<'_, Option<T>>,
1079        reader: FieldReader<'a, '_, R>,
1080    ) -> Result<()> {
1081        let v = item.take().flatten();
1082        crate::inplace!(v);
1083        E::read_field_in_sequence(&mut v, reader)?;
1084        item.set(Some(
1085            v.take().expect("read_field should have set the value"),
1086        ));
1087        Ok(())
1088    }
1089
1090    fn default_field(item: &mut InplaceOption<'_, Option<T>>) -> Result<()> {
1091        item.set(None);
1092        Ok(())
1093    }
1094
1095    fn wrap_in_sequence() -> bool {
1096        true
1097    }
1098}
1099
1100/// A field encoder for `Vec`.
1101pub struct VecField<E>(E);
1102
1103impl<T, E: DescribeField<T>> DescribeField<Vec<T>> for VecField<E> {
1104    const FIELD_TYPE: FieldType<'static> = {
1105        if let Some(packed) = E::PACKED_TYPE {
1106            FieldType::builtin(packed)
1107        } else if E::FIELD_TYPE.is_sequence() {
1108            FieldType::tuple(&[E::FIELD_TYPE]).repeated()
1109        } else {
1110            E::FIELD_TYPE.repeated()
1111        }
1112    };
1113}
1114
1115impl<T, R, E: FieldEncode<T, R>> FieldEncode<Vec<T>, R> for VecField<E> {
1116    fn write_field(item: Vec<T>, writer: FieldWriter<'_, '_, R>) {
1117        // Write a packed encoding if possible
1118        if let Some(packed_encode) = E::packed() {
1119            writer.packed(|packed| packed_encode.write_packed(item.as_slice(), packed));
1120        } else {
1121            let mut writer = writer.sequence();
1122            for item in item {
1123                E::write_field_in_sequence(item, &mut writer);
1124            }
1125        }
1126    }
1127
1128    fn compute_field_size(item: &mut Vec<T>, sizer: FieldSizer<'_>) {
1129        if let Some(packed_encode) = E::packed() {
1130            sizer.packed(|packed| packed_encode.compute_packed_size(item.as_slice(), packed));
1131        } else {
1132            let mut sizer = sizer.sequence();
1133            for item in item {
1134                E::compute_field_size_in_sequence(item, &mut sizer);
1135            }
1136        }
1137    }
1138
1139    fn wrap_in_sequence() -> bool {
1140        // `Vec<u8>` is encoded as a bytes value and not a repeated sequence.
1141        // Other packed sequences may still get a bytes value at runtime, but
1142        // they also support non-packed encodings and so must be wrapped when
1143        // they're nested in another sequence.
1144        let bytes = E::packed().is_some_and(|p| p.must_pack());
1145        !bytes
1146    }
1147}
1148
1149impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Vec<T>, R> for VecField<E> {
1150    fn read_field(
1151        item: &mut InplaceOption<'_, Vec<T>>,
1152        reader: FieldReader<'a, '_, R>,
1153    ) -> Result<()> {
1154        let vec = item.get_or_insert(Vec::new());
1155
1156        // Try to read the packed encoding if possible/required.
1157        if let Some(packed_decode) = E::packed() {
1158            if packed_decode.must_pack() || reader.wire_type() == WireType::Variable {
1159                packed_decode.read_packed(vec, &mut reader.packed()?)?;
1160                return Ok(());
1161            }
1162        }
1163
1164        // Construct the element in the vector in place.
1165        vec.reserve(1);
1166        // SAFETY: at least one value is allocated beyond len() due to the
1167        // reserve above and is safe to initialize.
1168        let v = unsafe { &mut *vec.as_mut_ptr().add(vec.len()).cast::<MaybeUninit<T>>() };
1169        let mut v = InplaceOption::uninit(v);
1170        E::read_field_in_sequence(&mut v, reader)?;
1171        assert!(v.forget(), "value should be constructed");
1172        // SAFETY: the element at vec.len() is now initialized.
1173        unsafe {
1174            vec.set_len(vec.len() + 1);
1175        }
1176        Ok(())
1177    }
1178
1179    fn default_field(item: &mut InplaceOption<'_, Vec<T>>) -> Result<()> {
1180        item.set(Vec::new());
1181        Ok(())
1182    }
1183
1184    fn wrap_in_sequence() -> bool {
1185        // `Vec<u8>` is encoded as a bytes value and not a repeated sequence.
1186        // Other packed sequences may still get a bytes value at runtime, but
1187        // they also support non-packed encodings and so must be wrapped when
1188        // they're nested in another sequence.
1189        let bytes = E::packed::<Vec<T>>().is_some_and(|p| p.must_pack());
1190        !bytes
1191    }
1192}
1193
1194/// A field encoder for maps from `K` to `V`, using encoders `EK` and `EV`.
1195pub struct MapField<K, V, EK, EV>(EK, EV, PhantomData<fn(K, V) -> (K, V)>);
1196
1197impl<T, K, V, EK: DescribeField<K>, EV: DescribeField<V>> DescribeField<T>
1198    for MapField<K, V, EK, EV>
1199{
1200    const FIELD_TYPE: FieldType<'static> = FieldType::map(&[EK::FIELD_TYPE, EV::FIELD_TYPE]);
1201}
1202
1203/// Encoder for pairs.
1204///
1205/// This is separate from the standard tuple encoder so that we can specify the
1206/// precise encoder to use.
1207///
1208/// FUTURE: replat this on top of table-based encoding.
1209struct PairEncoder<E, F>(E, F);
1210
1211impl<T, U, E, F, R> FieldEncode<(T, U), R> for PairEncoder<E, F>
1212where
1213    E: FieldEncode<T, R>,
1214    F: FieldEncode<U, R>,
1215{
1216    fn write_field(item: (T, U), writer: FieldWriter<'_, '_, R>) {
1217        writer.message(|mut writer| {
1218            E::write_field(item.0, writer.field(1));
1219            F::write_field(item.1, writer.field(2));
1220        })
1221    }
1222
1223    fn compute_field_size(item: &mut (T, U), sizer: FieldSizer<'_>) {
1224        sizer.message(|mut sizer| {
1225            E::compute_field_size(&mut item.0, sizer.field(1));
1226            F::compute_field_size(&mut item.1, sizer.field(2));
1227        })
1228    }
1229}
1230
1231impl<'a, T, U, E, F, R> FieldDecode<'a, (T, U), R> for PairEncoder<E, F>
1232where
1233    E: FieldDecode<'a, T, R>,
1234    F: FieldDecode<'a, U, R>,
1235{
1236    fn read_field(
1237        item: &mut InplaceOption<'_, (T, U)>,
1238        reader: FieldReader<'a, '_, R>,
1239    ) -> Result<()> {
1240        inplace_none!(t);
1241        inplace_none!(u);
1242        for field in reader.message()? {
1243            let (number, reader) = field?;
1244            match number {
1245                1 => {
1246                    E::read_field(&mut t, reader)?;
1247                }
1248                2 => {
1249                    F::read_field(&mut u, reader)?;
1250                }
1251                _ => {}
1252            }
1253        }
1254        if t.is_none() {
1255            E::default_field(&mut t)?;
1256        }
1257        if u.is_none() {
1258            F::default_field(&mut u)?;
1259        }
1260        item.set((t.take().unwrap(), u.take().unwrap()));
1261        Ok(())
1262    }
1263
1264    fn default_field(item: &mut InplaceOption<'_, (T, U)>) -> Result<()> {
1265        inplace_none!(t);
1266        E::default_field(&mut t)?;
1267        inplace_none!(u);
1268        F::default_field(&mut u)?;
1269        item.set((t.take().unwrap(), u.take().unwrap()));
1270        Ok(())
1271    }
1272}
1273
1274impl<K, V, T, EK, EV, R> FieldEncode<T, R> for MapField<K, V, EK, EV>
1275where
1276    T: IntoIterator<Item = (K, V)>,
1277    for<'a> &'a mut T: IntoIterator<Item = (&'a K, &'a mut V)>,
1278    for<'a> EK: FieldEncode<&'a K, R>,
1279    EV: FieldEncode<V, R>,
1280{
1281    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
1282        let mut writer = writer.sequence();
1283        for (k, v) in item {
1284            PairEncoder::<EK, EV>::write_field_in_sequence((&k, v), &mut writer);
1285        }
1286    }
1287
1288    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
1289        let mut sizer = sizer.sequence();
1290        for (mut k, v) in item {
1291            sizer.field().message(|mut sizer| {
1292                EK::compute_field_size(&mut k, sizer.field(1));
1293                EV::compute_field_size(v, sizer.field(2));
1294            });
1295        }
1296    }
1297
1298    fn wrap_in_sequence() -> bool {
1299        true
1300    }
1301}
1302
1303impl<'a, K, V, T, EK, EV, R> FieldDecode<'a, T, R> for MapField<K, V, EK, EV>
1304where
1305    T: Default + Extend<(K, V)>,
1306    EK: FieldDecode<'a, K, R>,
1307    EV: FieldDecode<'a, V, R>,
1308{
1309    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
1310        inplace_none!(v);
1311        PairEncoder::<EK, EV>::read_field(&mut v, reader)?;
1312        item.get_or_insert_with(Default::default).extend(v.take());
1313        Ok(())
1314    }
1315
1316    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
1317        item.get_or_insert_with(Default::default);
1318        Ok(())
1319    }
1320
1321    fn wrap_in_sequence() -> bool {
1322        true
1323    }
1324}
1325
1326/// A field encoder for fields that should be ignored.
1327pub struct IgnoreField;
1328
1329impl<T: Default, R> FieldEncode<T, R> for IgnoreField {
1330    fn write_field(_item: T, writer: FieldWriter<'_, '_, R>) {
1331        // No-op if not in a sequence.
1332        writer.message(|_| ());
1333    }
1334
1335    fn compute_field_size(_item: &mut T, sizer: FieldSizer<'_>) {
1336        // No-op if not in a sequence.
1337        sizer.message(|_| ());
1338    }
1339}
1340
1341impl<T: Default, R> FieldDecode<'_, T, R> for IgnoreField {
1342    fn read_field(_item: &mut InplaceOption<'_, T>, _reader: FieldReader<'_, '_, R>) -> Result<()> {
1343        Ok(())
1344    }
1345
1346    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
1347        item.set(Default::default());
1348        Ok(())
1349    }
1350}
1351
1352/// A field and message encoder for fields that cannot be instantiated.
1353pub struct ImpossibleField;
1354
1355impl<T> DescribeMessage<T> for ImpossibleField {
1356    const DESCRIPTION: MessageDescription<'static> = MessageDescription::External {
1357        name: "google.protobuf.Empty",
1358        import_path: "google/protobuf/empty.proto",
1359    };
1360}
1361
1362impl<T, R> FieldEncode<T, R> for ImpossibleField {
1363    fn write_field(_item: T, _writer: FieldWriter<'_, '_, R>) {
1364        unreachable!()
1365    }
1366
1367    fn compute_field_size(_item: &mut T, _sizer: FieldSizer<'_>) {
1368        unreachable!()
1369    }
1370}
1371
1372impl<T, R> FieldDecode<'_, T, R> for ImpossibleField {
1373    fn read_field(_item: &mut InplaceOption<'_, T>, _reader: FieldReader<'_, '_, R>) -> Result<()> {
1374        Err(DecodeError::Unexpected.into())
1375    }
1376
1377    fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<()> {
1378        Err(DecodeError::Unexpected.into())
1379    }
1380}
1381
1382impl<T, R> MessageEncode<T, R> for ImpossibleField {
1383    fn write_message(_item: T, _writer: MessageWriter<'_, '_, R>) {
1384        unreachable!()
1385    }
1386
1387    fn compute_message_size(_item: &mut T, _sizer: MessageSizer<'_>) {
1388        unreachable!()
1389    }
1390}
1391
1392impl<T, R> MessageDecode<'_, T, R> for ImpossibleField {
1393    fn read_message(
1394        _item: &mut InplaceOption<'_, T>,
1395        _reader: MessageReader<'_, '_, R>,
1396    ) -> Result<()> {
1397        Err(DecodeError::Unexpected.into())
1398    }
1399}
1400
1401/// A field encoder for fixed-sized arrays.
1402pub struct ArrayField<E>(E);
1403
1404impl<T, E: DescribeField<T>, const N: usize> DescribeField<[T; N]> for ArrayField<E> {
1405    const FIELD_TYPE: FieldType<'static> = {
1406        if let Some(packed) = E::PACKED_TYPE {
1407            FieldType::builtin(packed)
1408        } else if E::FIELD_TYPE.can_pack() {
1409            // BUGBUG: this is not protobuf compatible because protobuf allows
1410            // the unpacked encoding, which is not supported by `ArrayField`.
1411            // Change this once existing users are updated to use a different
1412            // type with a compatible encoding.
1413            E::FIELD_TYPE.repeated().annotate("packed repr only")
1414        } else {
1415            // Wrap in a message.
1416            FieldType::tuple(
1417                const {
1418                    if E::FIELD_TYPE.is_sequence() {
1419                        &[FieldType::tuple(&[E::FIELD_TYPE]).repeated()]
1420                    } else {
1421                        &[E::FIELD_TYPE.repeated()]
1422                    }
1423                },
1424            )
1425        }
1426    };
1427}
1428
1429impl<T, R, E: FieldEncode<T, R>, const N: usize> FieldEncode<[T; N], R> for ArrayField<E> {
1430    fn write_field(item: [T; N], writer: FieldWriter<'_, '_, R>) {
1431        if let Some(packed_encode) = E::packed() {
1432            writer.packed(|packed| packed_encode.write_packed(&item, packed));
1433        } else {
1434            // The fixed array has to be wrapped in an object to support
1435            // reading.
1436            writer.message(|mut message| {
1437                let mut writer = message.field(1).sequence();
1438                for v in item {
1439                    E::write_field_in_sequence(v, &mut writer);
1440                }
1441            });
1442        }
1443    }
1444
1445    fn compute_field_size(item: &mut [T; N], sizer: FieldSizer<'_>) {
1446        if let Some(packed_encode) = E::packed() {
1447            sizer.packed(|packed| packed_encode.compute_packed_size(item, packed));
1448        } else {
1449            sizer.message(|mut message| {
1450                let mut sizer = message.field(1).sequence();
1451                for v in item {
1452                    E::compute_field_size_in_sequence(v, &mut sizer);
1453                }
1454            });
1455        }
1456    }
1457}
1458
1459impl<'a, T, R, E: FieldDecode<'a, T, R>, const N: usize> FieldDecode<'a, [T; N], R>
1460    for ArrayField<E>
1461{
1462    fn read_field(
1463        item: &mut InplaceOption<'_, [T; N]>,
1464        reader: FieldReader<'a, '_, R>,
1465    ) -> Result<()> {
1466        if let Some(packed_decode) = E::packed() {
1467            let mut vec = Vec::with_capacity(N); // TODO: use an in-place mechanism
1468            packed_decode.read_packed(&mut vec, &mut reader.packed()?)?;
1469            item.set(
1470                vec.try_into()
1471                    .map_err(|_| DecodeError::BadPackedArrayLength)?,
1472            );
1473        } else {
1474            let vec = Vec::with_capacity(N); // TODO: use an in-place mechanism
1475            inplace_some!(vec);
1476            VecField::<E>::read_field_in_sequence(&mut vec, reader)?;
1477            item.set(
1478                vec.take()
1479                    .expect("should still be set")
1480                    .try_into()
1481                    .map_err(|_| DecodeError::BadArrayLength)?,
1482            );
1483        }
1484        Ok(())
1485    }
1486
1487    fn default_field(_item: &mut InplaceOption<'_, [T; N]>) -> Result<()> {
1488        // TODO
1489        Err(DecodeError::MissingRequiredField.into())
1490    }
1491}
1492
1493/// A field encoding for C-format structs.
1494///
1495/// Messages will be encoded as `bytes` fields whose size must exactly match the
1496/// struct's size.
1497///
1498/// Missing fields will be zero-initialized during message decode.
1499pub struct ZeroCopyEncoding;
1500
1501impl<T> DescribeField<T> for ZeroCopyEncoding {
1502    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("bytes");
1503}
1504
1505#[derive(Debug, Error)]
1506#[error("invalid byte size for type")]
1507struct InvalidZeroCopySize;
1508
1509impl<T: zerocopy::IntoBytes + Immutable + KnownLayout, R> FieldEncode<T, R> for ZeroCopyEncoding {
1510    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
1511        writer.bytes(item.as_bytes());
1512    }
1513
1514    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
1515        sizer.bytes(item.as_bytes().len());
1516    }
1517}
1518
1519impl<'a, T: zerocopy::FromBytes + Immutable + KnownLayout, R> FieldDecode<'a, T, R>
1520    for ZeroCopyEncoding
1521{
1522    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
1523        item.set(T::read_from_bytes(reader.bytes()?).map_err(|_| Error::new(InvalidZeroCopySize))?); // TODO: zerocopy: better use error here (https://github.com/microsoft/openvmm/issues/759)
1524        Ok(())
1525    }
1526
1527    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
1528        item.set(T::new_zeroed());
1529        Ok(())
1530    }
1531}
1532
1533/// A wrapper encoding for boxed data.
1534///
1535/// Messages and fields are handled as if they are not boxed, except that they
1536/// are never encoded in packed format.
1537pub struct BoxEncoding<E>(E);
1538
1539impl<E: DescribeField<T>, T> DescribeField<T> for BoxEncoding<E> {
1540    const FIELD_TYPE: FieldType<'static> = E::FIELD_TYPE;
1541}
1542
1543impl<E: DescribeMessage<T>, T> DescribeMessage<T> for BoxEncoding<E> {
1544    const DESCRIPTION: MessageDescription<'static> = E::DESCRIPTION;
1545}
1546
1547impl<T, R, E: MessageEncode<T, R>> MessageEncode<Box<T>, R> for BoxEncoding<E> {
1548    fn write_message(item: Box<T>, writer: MessageWriter<'_, '_, R>) {
1549        E::write_message(*item, writer)
1550    }
1551
1552    fn compute_message_size(item: &mut Box<T>, sizer: MessageSizer<'_>) {
1553        E::compute_message_size(&mut *item, sizer)
1554    }
1555}
1556
1557impl<'a, T, R, E: MessageDecode<'a, T, R>> MessageDecode<'a, Box<T>, R> for BoxEncoding<E> {
1558    fn read_message(
1559        item: &mut InplaceOption<'_, Box<T>>,
1560        reader: MessageReader<'a, '_, R>,
1561    ) -> Result<()> {
1562        item.update_box(|item| E::read_message(item, reader))
1563    }
1564}
1565
1566impl<T, R, E: FieldEncode<T, R>> FieldEncode<Box<T>, R> for BoxEncoding<E> {
1567    fn write_field(item: Box<T>, writer: FieldWriter<'_, '_, R>) {
1568        E::write_field(*item, writer)
1569    }
1570
1571    fn compute_field_size(item: &mut Box<T>, sizer: FieldSizer<'_>) {
1572        E::compute_field_size(&mut *item, sizer)
1573    }
1574
1575    fn wrap_in_sequence() -> bool {
1576        E::wrap_in_sequence()
1577    }
1578}
1579
1580impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Box<T>, R> for BoxEncoding<E> {
1581    fn read_field(
1582        item: &mut InplaceOption<'_, Box<T>>,
1583        reader: FieldReader<'a, '_, R>,
1584    ) -> Result<()> {
1585        item.update_box(|item| E::read_field(item, reader))
1586    }
1587
1588    fn default_field(item: &mut InplaceOption<'_, Box<T>>) -> Result<()> {
1589        item.update_box(|item| E::default_field(item))
1590    }
1591
1592    fn wrap_in_sequence() -> bool {
1593        E::wrap_in_sequence()
1594    }
1595}
1596
1597/// A wrapper encoding for reference-counted data.
1598///
1599/// If the `Arc<T>` is the sole owner of T, then T is serialized as-is. If there
1600/// are other references, then the T is first cloned so that there is a single
1601/// instance.
1602///
1603/// Messages and fields are handled as if they are not reference counted, except
1604/// that they are never encoded in packed format.
1605pub struct ArcEncoding<E>(E);
1606
1607impl<E: DescribeField<T>, T> DescribeField<T> for ArcEncoding<E> {
1608    const FIELD_TYPE: FieldType<'static> = E::FIELD_TYPE;
1609}
1610
1611impl<E: DescribeMessage<T>, T> DescribeMessage<T> for ArcEncoding<E> {
1612    const DESCRIPTION: MessageDescription<'static> = E::DESCRIPTION;
1613}
1614
1615impl<T: Clone, R, E: MessageEncode<T, R>> MessageEncode<Arc<T>, R> for ArcEncoding<E> {
1616    fn write_message(item: Arc<T>, writer: MessageWriter<'_, '_, R>) {
1617        E::write_message(
1618            Arc::try_unwrap(item)
1619                .ok()
1620                .expect("compute_message_size ensured single instance"),
1621            writer,
1622        )
1623    }
1624
1625    fn compute_message_size(item: &mut Arc<T>, sizer: MessageSizer<'_>) {
1626        E::compute_message_size(Arc::make_mut(item), sizer)
1627    }
1628}
1629
1630impl<'a, T: Clone, R, E: MessageDecode<'a, T, R>> MessageDecode<'a, Arc<T>, R> for ArcEncoding<E> {
1631    fn read_message(
1632        item: &mut InplaceOption<'_, Arc<T>>,
1633        reader: MessageReader<'a, '_, R>,
1634    ) -> Result<()> {
1635        item.update_arc(|item| E::read_message(item, reader))
1636    }
1637}
1638
1639impl<T: Clone, R, E: FieldEncode<T, R>> FieldEncode<Arc<T>, R> for ArcEncoding<E> {
1640    fn write_field(item: Arc<T>, writer: FieldWriter<'_, '_, R>) {
1641        E::write_field(
1642            Arc::try_unwrap(item)
1643                .ok()
1644                .expect("compute_field_size ensured single instance"),
1645            writer,
1646        )
1647    }
1648
1649    fn compute_field_size(item: &mut Arc<T>, sizer: FieldSizer<'_>) {
1650        E::compute_field_size(Arc::make_mut(item), sizer)
1651    }
1652
1653    fn wrap_in_sequence() -> bool {
1654        E::wrap_in_sequence()
1655    }
1656}
1657
1658impl<'a, T: Clone, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Arc<T>, R> for ArcEncoding<E> {
1659    fn read_field(
1660        item: &mut InplaceOption<'_, Arc<T>>,
1661        reader: FieldReader<'a, '_, R>,
1662    ) -> Result<()> {
1663        item.update_arc(|item| E::read_field(item, reader))
1664    }
1665
1666    fn default_field(item: &mut InplaceOption<'_, Arc<T>>) -> Result<()> {
1667        item.update_arc(|item| E::default_field(item))
1668    }
1669
1670    fn wrap_in_sequence() -> bool {
1671        E::wrap_in_sequence()
1672    }
1673}
1674
1675macro_rules! default_encodings {
1676    ($($(#[$attr:meta])* $ty:ty: $mp:ty),* $(,)?) => {
1677        $(
1678            $(
1679                #[$attr]
1680            )*
1681            impl $crate::DefaultEncoding for $ty {
1682                type Encoding = $mp;
1683            }
1684        )*
1685    };
1686}
1687
1688// Set the default encodings for common Rust types.
1689default_encodings! {
1690    u8: ByteField,
1691    u16: VarintField,
1692    u32: VarintField,
1693    u64: VarintField,
1694    u128: U128LittleEndianField,
1695    Wrapping<u64>: VarintField,
1696    usize: VarintField,
1697    bool: VarintField,
1698    char: VarintField,
1699
1700    i8: SignedVarintField,
1701    i16: SignedVarintField,
1702    i32: SignedVarintField,
1703    i64: SignedVarintField,
1704    isize: SignedVarintField,
1705
1706    f64: Fixed64Field,
1707    f32: Fixed32Field,
1708
1709    NonZeroU8: VarintField,
1710    NonZeroU16: VarintField,
1711    NonZeroU32: VarintField,
1712    NonZeroU64: VarintField,
1713    NonZeroUsize: VarintField,
1714    NonZeroI8: SignedVarintField,
1715    NonZeroI16: SignedVarintField,
1716    NonZeroI32: SignedVarintField,
1717    NonZeroI64: SignedVarintField,
1718    NonZeroIsize: SignedVarintField,
1719
1720    String: StringField,
1721
1722    Duration: MessageEncoding<DurationEncoding>,
1723
1724    Infallible: ImpossibleField,
1725
1726    core::net::Ipv4Addr: Fixed32Field,
1727    core::net::Ipv6Addr: Ipv6AddrField,
1728}
1729
1730impl DefaultEncoding for &str {
1731    type Encoding = StringField;
1732}
1733
1734impl DefaultEncoding for &[u8] {
1735    type Encoding = BytesField;
1736}
1737
1738impl DefaultEncoding for Cow<'_, str> {
1739    type Encoding = StringField;
1740}
1741
1742impl<T: DefaultEncoding> DefaultEncoding for Option<T> {
1743    type Encoding = OptionField<T::Encoding>;
1744}
1745
1746impl<T: DefaultEncoding> DefaultEncoding for Vec<T> {
1747    type Encoding = VecField<T::Encoding>;
1748}
1749
1750#[cfg(feature = "std")]
1751impl<K: DefaultEncoding, V: DefaultEncoding> DefaultEncoding for std::collections::HashMap<K, V> {
1752    type Encoding = MapField<K, V, K::Encoding, V::Encoding>;
1753}
1754
1755impl<K: DefaultEncoding, V: DefaultEncoding> DefaultEncoding for BTreeMap<K, V> {
1756    type Encoding = MapField<K, V, K::Encoding, V::Encoding>;
1757}
1758
1759impl<T> DefaultEncoding for PhantomData<T> {
1760    type Encoding = IgnoreField;
1761}
1762
1763impl<T: DefaultEncoding, const N: usize> DefaultEncoding for [T; N] {
1764    type Encoding = ArrayField<T::Encoding>;
1765}
1766
1767impl<T: DefaultEncoding> DefaultEncoding for Box<T> {
1768    type Encoding = BoxEncoding<T::Encoding>;
1769}
1770
1771impl<T: DefaultEncoding + Clone> DefaultEncoding for Arc<T> {
1772    type Encoding = ArcEncoding<T::Encoding>;
1773}
1774
1775// Derive an encoding for `Result`.
1776#[derive(mesh_derive::Protobuf)]
1777#[mesh(impl_for = "::core::result::Result")]
1778#[expect(dead_code)]
1779enum ResultAsPayload<T, U> {
1780    #[mesh(transparent)]
1781    Ok(T),
1782    #[mesh(transparent)]
1783    Err(U),
1784}
1785
1786// Derive an encoding for `Range`.
1787#[derive(mesh_derive::Protobuf)]
1788#[mesh(impl_for = "::core::ops::Range")]
1789#[expect(dead_code)]
1790struct RangeAsPayload<T> {
1791    start: T,
1792    end: T,
1793}
1794
1795/// An encoder for [`SerializedMessage`].
1796pub struct SerializedMessageEncoder;
1797
1798impl<R> MessageEncode<SerializedMessage<R>, R> for SerializedMessageEncoder {
1799    fn write_message(item: SerializedMessage<R>, mut writer: MessageWriter<'_, '_, R>) {
1800        writer.raw_message(&item.data, item.resources);
1801    }
1802
1803    fn compute_message_size(item: &mut SerializedMessage<R>, mut sizer: MessageSizer<'_>) {
1804        sizer.raw_message(item.data.len(), item.resources.len() as u32);
1805    }
1806}
1807
1808impl<R> MessageDecode<'_, SerializedMessage<R>, R> for SerializedMessageEncoder {
1809    fn read_message(
1810        item: &mut InplaceOption<'_, SerializedMessage<R>>,
1811        mut reader: MessageReader<'_, '_, R>,
1812    ) -> Result<()> {
1813        let resources = reader.take_resources();
1814        match item.as_mut() {
1815            Some(message) => {
1816                // Protobuf messages are merged just by adding in the extra
1817                // fields to the end. This works even with ports and resources
1818                // present.
1819                message.data.extend(reader.bytes());
1820                for resource in reader.take_resources() {
1821                    message.resources.push(resource?);
1822                }
1823            }
1824            None => {
1825                item.set(SerializedMessage {
1826                    data: reader.bytes().to_vec(),
1827                    resources: resources.collect::<Result<_>>()?,
1828                });
1829            }
1830        }
1831        Ok(())
1832    }
1833}
1834
1835impl<R> DefaultEncoding for SerializedMessage<R> {
1836    type Encoding = MessageEncoding<SerializedMessageEncoder>;
1837}
1838
1839/// A field encoder for types that can be converted to and from OS resource type
1840/// `T`.
1841pub struct ResourceField<T>(PhantomData<T>);
1842
1843impl<T> Default for ResourceField<T> {
1844    fn default() -> Self {
1845        Self(PhantomData)
1846    }
1847}
1848
1849impl<T, U, R> FieldEncode<T, R> for ResourceField<U>
1850where
1851    T: Into<U>,
1852    U: Into<R>,
1853{
1854    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
1855        writer.resource(item.into().into());
1856    }
1857
1858    fn compute_field_size(_item: &mut T, sizer: FieldSizer<'_>) {
1859        sizer.resource();
1860    }
1861}
1862
1863impl<T, U, R> FieldDecode<'_, T, R> for ResourceField<U>
1864where
1865    T: From<U>,
1866    U: TryFrom<R>,
1867    U::Error: 'static + core::error::Error + Send + Sync,
1868{
1869    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
1870        let resource = T::from(reader.resource()?.try_into().map_err(Error::new)?);
1871        item.set(resource);
1872        Ok(())
1873    }
1874
1875    fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<()> {
1876        Err(DecodeError::MissingResource.into())
1877    }
1878}
1879
1880/// Implements [`DefaultEncoding`] for OS resources.
1881///
1882/// The specified type must implement `From<R>` and `Into<R>`, where `R` is the
1883/// underlying OS resource type (such as `OwnedFd` or `OwnedHandle`).
1884#[macro_export]
1885macro_rules! os_resource {
1886    ($ty:ty, $resource_ty:ty) => {
1887        impl $crate::DefaultEncoding for $ty {
1888            type Encoding = $crate::encoding::ResourceField<$resource_ty>;
1889        }
1890    };
1891}
1892
1893#[cfg(all(feature = "std", windows))]
1894mod windows {
1895    use crate::os_resource;
1896    use std::os::windows::prelude::*;
1897
1898    os_resource!(OwnedHandle, OwnedHandle);
1899    os_resource!(std::fs::File, OwnedHandle);
1900
1901    os_resource!(OwnedSocket, OwnedSocket);
1902    os_resource!(std::net::TcpListener, OwnedSocket);
1903    os_resource!(std::net::TcpStream, OwnedSocket);
1904    os_resource!(std::net::UdpSocket, OwnedSocket);
1905
1906    #[cfg(feature = "socket2")]
1907    os_resource!(socket2::Socket, OwnedSocket);
1908}
1909
1910#[cfg(all(feature = "std", unix))]
1911mod unix {
1912    use crate::os_resource;
1913    use std::os::unix::prelude::*;
1914
1915    os_resource!(OwnedFd, OwnedFd);
1916    os_resource!(std::fs::File, OwnedFd);
1917    os_resource!(std::os::unix::net::UnixListener, OwnedFd);
1918    os_resource!(std::os::unix::net::UnixStream, OwnedFd);
1919    os_resource!(std::net::TcpListener, OwnedFd);
1920    os_resource!(std::net::TcpStream, OwnedFd);
1921    os_resource!(std::net::UdpSocket, OwnedFd);
1922
1923    #[cfg(feature = "socket2")]
1924    os_resource!(socket2::Socket, OwnedFd);
1925}