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");
693
694impl<T: ToNumber, R> FieldEncode<T, R> for SignedVarintField {
695    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
696        writer.svarint(item.to_i64())
697    }
698
699    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
700        sizer.svarint(item.to_i64())
701    }
702
703    fn packed<'a>() -> Option<&'a dyn PackedEncode<T>>
704    where
705        T: 'a,
706    {
707        Some(&Self)
708    }
709}
710
711impl<T: ToNumber> PackedEncode<T> for SignedVarintField {
712    fn write_packed(&self, data: &[T], mut writer: PackedWriter<'_, '_>) {
713        for v in data {
714            writer.svarint(v.to_i64());
715        }
716    }
717
718    fn compute_packed_size(&self, data: &[T], mut sizer: PackedSizer<'_>) {
719        for v in data {
720            sizer.svarint(v.to_i64());
721        }
722    }
723
724    fn must_pack(&self) -> bool {
725        false
726    }
727}
728
729impl<'a, T: FromNumber, R> FieldDecode<'a, T, R> for SignedVarintField {
730    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
731        item.set(T::from_i64(reader.svarint()?)?);
732        Ok(())
733    }
734
735    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
736        item.set(T::from_i64(0).unwrap());
737        Ok(())
738    }
739
740    fn packed<'p, C: CopyExtend<T>>() -> Option<&'p dyn PackedDecode<'a, T, C>>
741    where
742        T: 'p,
743    {
744        Some(&Self)
745    }
746}
747
748impl<T: FromNumber, C: CopyExtend<T>> PackedDecode<'_, T, C> for SignedVarintField {
749    fn read_packed(&self, data: &mut C, reader: &mut PackedReader<'_>) -> Result<()> {
750        while let Some(v) = reader.svarint()? {
751            data.push(T::from_i64(v)?);
752        }
753        Ok(())
754    }
755
756    fn must_pack(&self) -> bool {
757        false
758    }
759}
760
761/// A field encoder for u128.
762///
763/// Writes the value as a little-endian-encoded 16-byte byte array.
764pub struct U128LittleEndianField;
765
766builtin_field_type!(u128, U128LittleEndianField, "bytes");
767
768impl<T: Copy + Into<u128>, R> FieldEncode<T, R> for U128LittleEndianField {
769    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
770        let item = item.into();
771        if item != 0 || writer.write_empty() {
772            writer.bytes(&item.to_le_bytes());
773        }
774    }
775
776    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
777        let item = (*item).into();
778        if item != 0 || sizer.write_empty() {
779            sizer.bytes(16);
780        }
781    }
782}
783
784impl<T: From<u128>, R> FieldDecode<'_, T, R> for U128LittleEndianField {
785    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
786        item.set(
787            u128::from_le_bytes(
788                reader
789                    .bytes()?
790                    .try_into()
791                    .map_err(|_| DecodeError::BadU128)?,
792            )
793            .into(),
794        );
795        Ok(())
796    }
797
798    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
799        item.set(0.into());
800        Ok(())
801    }
802}
803
804/// A field encoder for an IPv6 address.
805///
806/// Writes the value in octet order as a 16-byte array.
807pub struct Ipv6AddrField;
808
809builtin_field_type!(core::net::Ipv6Addr, Ipv6AddrField, "bytes");
810
811impl<R> FieldEncode<core::net::Ipv6Addr, R> for Ipv6AddrField {
812    fn write_field(item: core::net::Ipv6Addr, writer: FieldWriter<'_, '_, R>) {
813        if !item.is_unspecified() || writer.write_empty() {
814            writer.bytes(&item.octets());
815        }
816    }
817
818    fn compute_field_size(item: &mut core::net::Ipv6Addr, sizer: FieldSizer<'_>) {
819        if !item.is_unspecified() || sizer.write_empty() {
820            sizer.bytes(16);
821        }
822    }
823}
824
825impl<R> FieldDecode<'_, core::net::Ipv6Addr, R> for Ipv6AddrField {
826    fn read_field(
827        item: &mut InplaceOption<'_, core::net::Ipv6Addr>,
828        reader: FieldReader<'_, '_, R>,
829    ) -> Result<()> {
830        let v: [u8; 16] = reader
831            .bytes()?
832            .try_into()
833            .map_err(|_| DecodeError::BadIpv6)?;
834
835        item.set(v.into());
836        Ok(())
837    }
838
839    fn default_field(item: &mut InplaceOption<'_, core::net::Ipv6Addr>) -> Result<()> {
840        item.set(core::net::Ipv6Addr::UNSPECIFIED);
841        Ok(())
842    }
843}
844
845/// A field encoder for byte streams.
846pub struct BytesField;
847
848impl<T: AsRef<[u8]>> DescribeField<T> for BytesField {
849    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("bytes");
850}
851
852impl<T: AsRef<[u8]>, R> FieldEncode<T, R> for BytesField {
853    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
854        writer.bytes(item.as_ref())
855    }
856
857    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
858        sizer.bytes(item.as_ref().len())
859    }
860}
861
862impl<'a, T: From<&'a [u8]> + Default, R> FieldDecode<'a, T, R> for BytesField {
863    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
864        item.set(reader.bytes()?.into());
865        Ok(())
866    }
867
868    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
869        item.set(Default::default());
870        Ok(())
871    }
872}
873
874/// A field encoder for strings.
875pub struct StringField;
876
877impl<T: AsRef<str>> DescribeField<T> for StringField {
878    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("string");
879}
880
881impl<T: AsRef<str>, R> FieldEncode<T, R> for StringField {
882    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
883        writer.bytes(item.as_ref().as_bytes())
884    }
885
886    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
887        sizer.bytes(item.as_ref().len())
888    }
889}
890
891impl<'a, T: From<&'a str> + Default, R> FieldDecode<'a, T, R> for StringField {
892    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
893        item.set(
894            core::str::from_utf8(reader.bytes()?)
895                .map_err(DecodeError::InvalidUtf8)?
896                .into(),
897        );
898        Ok(())
899    }
900
901    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
902        item.set(Default::default());
903        Ok(())
904    }
905}
906
907/// An encoder for `Cow<'a, str>` or `Cow<'a, [u8]>` that creates
908/// [`Cow::Borrowed`] on read.
909pub struct BorrowedCowField;
910
911impl DescribeField<Cow<'_, str>> for BorrowedCowField {
912    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("string");
913}
914
915impl<'a, R> FieldEncode<Cow<'a, str>, R> for BorrowedCowField {
916    fn write_field(item: Cow<'a, str>, writer: FieldWriter<'_, '_, R>) {
917        writer.bytes(item.as_bytes())
918    }
919
920    fn compute_field_size(item: &mut Cow<'a, str>, sizer: FieldSizer<'_>) {
921        sizer.bytes(item.len())
922    }
923}
924
925impl<'a, R> FieldDecode<'a, Cow<'a, str>, R> for BorrowedCowField {
926    fn read_field(
927        item: &mut InplaceOption<'_, Cow<'a, str>>,
928        reader: FieldReader<'a, '_, R>,
929    ) -> Result<()> {
930        item.set(Cow::Borrowed(
931            core::str::from_utf8(reader.bytes()?).map_err(DecodeError::InvalidUtf8)?,
932        ));
933        Ok(())
934    }
935
936    fn default_field(item: &mut InplaceOption<'_, Cow<'a, str>>) -> Result<()> {
937        item.set(Cow::Borrowed(""));
938        Ok(())
939    }
940}
941
942impl<'a, R> FieldEncode<Cow<'a, [u8]>, R> for BorrowedCowField {
943    fn write_field(item: Cow<'a, [u8]>, writer: FieldWriter<'_, '_, R>) {
944        writer.bytes(item.as_ref())
945    }
946
947    fn compute_field_size(item: &mut Cow<'a, [u8]>, sizer: FieldSizer<'_>) {
948        sizer.bytes(item.len())
949    }
950}
951
952impl<'a, R> FieldDecode<'a, Cow<'a, [u8]>, R> for BorrowedCowField {
953    fn read_field(
954        item: &mut InplaceOption<'_, Cow<'a, [u8]>>,
955        reader: FieldReader<'a, '_, R>,
956    ) -> Result<()> {
957        let bytes = reader.bytes()?;
958        let item = item.get_or_insert(Cow::Borrowed(&[]));
959        if item.is_empty() {
960            *item = Cow::Borrowed(bytes);
961        } else {
962            // Extend the bytes instead of replacing them to behave like protobuf's
963            // bytes fields.
964            item.to_mut().extend_from_slice(bytes);
965        }
966        Ok(())
967    }
968
969    fn default_field(item: &mut InplaceOption<'_, Cow<'a, [u8]>>) -> Result<()> {
970        item.set(Cow::Borrowed(&[]));
971        Ok(())
972    }
973}
974
975/// An encoder for `Cow<'a, str>` or `Cow<'a, [u8]>` that creates [`Cow::Owned`]
976/// on read.
977pub struct OwningCowField;
978
979impl DescribeField<Cow<'_, str>> for OwningCowField {
980    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("string");
981}
982
983impl<'a, R> FieldEncode<Cow<'a, str>, R> for OwningCowField {
984    fn write_field(item: Cow<'a, str>, writer: FieldWriter<'_, '_, R>) {
985        writer.bytes(item.as_bytes())
986    }
987
988    fn compute_field_size(item: &mut Cow<'a, str>, sizer: FieldSizer<'_>) {
989        sizer.bytes(item.len())
990    }
991}
992
993impl<'a, 'b, R> FieldDecode<'a, Cow<'b, str>, R> for OwningCowField {
994    fn read_field(
995        item: &mut InplaceOption<'_, Cow<'b, str>>,
996        reader: FieldReader<'a, '_, R>,
997    ) -> Result<()> {
998        item.set(Cow::Owned(
999            core::str::from_utf8(reader.bytes()?)
1000                .map_err(DecodeError::InvalidUtf8)?
1001                .into(),
1002        ));
1003        Ok(())
1004    }
1005
1006    fn default_field(item: &mut InplaceOption<'_, Cow<'b, str>>) -> Result<()> {
1007        item.set(Cow::Borrowed(""));
1008        Ok(())
1009    }
1010}
1011
1012impl<'a, R> FieldEncode<Cow<'a, [u8]>, R> for OwningCowField {
1013    fn write_field(item: Cow<'a, [u8]>, writer: FieldWriter<'_, '_, R>) {
1014        writer.bytes(item.as_ref())
1015    }
1016
1017    fn compute_field_size(item: &mut Cow<'a, [u8]>, sizer: FieldSizer<'_>) {
1018        sizer.bytes(item.len())
1019    }
1020}
1021
1022impl<'a, 'b, R> FieldDecode<'a, Cow<'b, [u8]>, R> for OwningCowField {
1023    fn read_field(
1024        item: &mut InplaceOption<'_, Cow<'b, [u8]>>,
1025        reader: FieldReader<'a, '_, R>,
1026    ) -> Result<()> {
1027        let bytes = reader.bytes()?;
1028        item.get_or_insert(Cow::Borrowed(&[]))
1029            .to_mut()
1030            .extend_from_slice(bytes);
1031        Ok(())
1032    }
1033
1034    fn default_field(item: &mut InplaceOption<'_, Cow<'b, [u8]>>) -> Result<()> {
1035        item.set(Cow::Borrowed(&[]));
1036        Ok(())
1037    }
1038}
1039
1040/// A field encoder for `Option`.
1041pub struct OptionField<E>(E);
1042
1043impl<T, E: DescribeField<T>> DescribeField<Option<T>> for OptionField<E> {
1044    const FIELD_TYPE: FieldType<'static> = {
1045        if E::FIELD_TYPE.is_sequence() {
1046            FieldType::tuple(&[E::FIELD_TYPE]).optional()
1047        } else {
1048            E::FIELD_TYPE.optional()
1049        }
1050    };
1051}
1052
1053impl<T, R, E: FieldEncode<T, R>> FieldEncode<Option<T>, R> for OptionField<E> {
1054    fn write_field(item: Option<T>, writer: FieldWriter<'_, '_, R>) {
1055        if let Some(v) = item {
1056            E::write_field_in_sequence(v, &mut writer.sequence())
1057        }
1058    }
1059
1060    fn compute_field_size(item: &mut Option<T>, sizer: FieldSizer<'_>) {
1061        if let Some(v) = item {
1062            E::compute_field_size_in_sequence(v, &mut sizer.sequence())
1063        }
1064    }
1065
1066    fn wrap_in_sequence() -> bool {
1067        true
1068    }
1069}
1070
1071impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Option<T>, R> for OptionField<E> {
1072    fn read_field(
1073        item: &mut InplaceOption<'_, Option<T>>,
1074        reader: FieldReader<'a, '_, R>,
1075    ) -> Result<()> {
1076        let v = item.take().flatten();
1077        crate::inplace!(v);
1078        E::read_field_in_sequence(&mut v, reader)?;
1079        item.set(Some(
1080            v.take().expect("read_field should have set the value"),
1081        ));
1082        Ok(())
1083    }
1084
1085    fn default_field(item: &mut InplaceOption<'_, Option<T>>) -> Result<()> {
1086        item.set(None);
1087        Ok(())
1088    }
1089
1090    fn wrap_in_sequence() -> bool {
1091        true
1092    }
1093}
1094
1095/// A field encoder for `Vec`.
1096pub struct VecField<E>(E);
1097
1098impl<T, E: DescribeField<T>> DescribeField<Vec<T>> for VecField<E> {
1099    const FIELD_TYPE: FieldType<'static> = {
1100        if let Some(packed) = E::PACKED_TYPE {
1101            FieldType::builtin(packed)
1102        } else if E::FIELD_TYPE.is_sequence() {
1103            FieldType::tuple(&[E::FIELD_TYPE]).repeated()
1104        } else {
1105            E::FIELD_TYPE.repeated()
1106        }
1107    };
1108}
1109
1110impl<T, R, E: FieldEncode<T, R>> FieldEncode<Vec<T>, R> for VecField<E> {
1111    fn write_field(item: Vec<T>, writer: FieldWriter<'_, '_, R>) {
1112        // Write a packed encoding if possible
1113        if let Some(packed_encode) = E::packed() {
1114            writer.packed(|packed| packed_encode.write_packed(item.as_slice(), packed));
1115        } else {
1116            let mut writer = writer.sequence();
1117            for item in item {
1118                E::write_field_in_sequence(item, &mut writer);
1119            }
1120        }
1121    }
1122
1123    fn compute_field_size(item: &mut Vec<T>, sizer: FieldSizer<'_>) {
1124        if let Some(packed_encode) = E::packed() {
1125            sizer.packed(|packed| packed_encode.compute_packed_size(item.as_slice(), packed));
1126        } else {
1127            let mut sizer = sizer.sequence();
1128            for item in item {
1129                E::compute_field_size_in_sequence(item, &mut sizer);
1130            }
1131        }
1132    }
1133
1134    fn wrap_in_sequence() -> bool {
1135        // `Vec<u8>` is encoded as a bytes value and not a repeated sequence.
1136        // Other packed sequences may still get a bytes value at runtime, but
1137        // they also support non-packed encodings and so must be wrapped when
1138        // they're nested in another sequence.
1139        let bytes = E::packed().is_some_and(|p| p.must_pack());
1140        !bytes
1141    }
1142}
1143
1144impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Vec<T>, R> for VecField<E> {
1145    fn read_field(
1146        item: &mut InplaceOption<'_, Vec<T>>,
1147        reader: FieldReader<'a, '_, R>,
1148    ) -> Result<()> {
1149        let vec = item.get_or_insert(Vec::new());
1150
1151        // Try to read the packed encoding if possible/required.
1152        if let Some(packed_decode) = E::packed() {
1153            if packed_decode.must_pack() || reader.wire_type() == WireType::Variable {
1154                packed_decode.read_packed(vec, &mut reader.packed()?)?;
1155                return Ok(());
1156            }
1157        }
1158
1159        // Construct the element in the vector in place.
1160        vec.reserve(1);
1161        // SAFETY: at least one value is allocated beyond len() due to the
1162        // reserve above and is safe to initialize.
1163        let v = unsafe { &mut *vec.as_mut_ptr().add(vec.len()).cast::<MaybeUninit<T>>() };
1164        let mut v = InplaceOption::uninit(v);
1165        E::read_field_in_sequence(&mut v, reader)?;
1166        assert!(v.forget(), "value should be constructed");
1167        // SAFETY: the element at vec.len() is now initialized.
1168        unsafe {
1169            vec.set_len(vec.len() + 1);
1170        }
1171        Ok(())
1172    }
1173
1174    fn default_field(item: &mut InplaceOption<'_, Vec<T>>) -> Result<()> {
1175        item.set(Vec::new());
1176        Ok(())
1177    }
1178
1179    fn wrap_in_sequence() -> bool {
1180        // `Vec<u8>` is encoded as a bytes value and not a repeated sequence.
1181        // Other packed sequences may still get a bytes value at runtime, but
1182        // they also support non-packed encodings and so must be wrapped when
1183        // they're nested in another sequence.
1184        let bytes = E::packed::<Vec<T>>().is_some_and(|p| p.must_pack());
1185        !bytes
1186    }
1187}
1188
1189/// A field encoder for maps from `K` to `V`, using encoders `EK` and `EV`.
1190pub struct MapField<K, V, EK, EV>(EK, EV, PhantomData<fn(K, V) -> (K, V)>);
1191
1192impl<T, K, V, EK: DescribeField<K>, EV: DescribeField<V>> DescribeField<T>
1193    for MapField<K, V, EK, EV>
1194{
1195    const FIELD_TYPE: FieldType<'static> = FieldType::map(&[EK::FIELD_TYPE, EV::FIELD_TYPE]);
1196}
1197
1198/// Encoder for pairs.
1199///
1200/// This is separate from the standard tuple encoder so that we can specify the
1201/// precise encoder to use.
1202///
1203/// FUTURE: replat this on top of table-based encoding.
1204struct PairEncoder<E, F>(E, F);
1205
1206impl<T, U, E, F, R> FieldEncode<(T, U), R> for PairEncoder<E, F>
1207where
1208    E: FieldEncode<T, R>,
1209    F: FieldEncode<U, R>,
1210{
1211    fn write_field(item: (T, U), writer: FieldWriter<'_, '_, R>) {
1212        writer.message(|mut writer| {
1213            E::write_field(item.0, writer.field(1));
1214            F::write_field(item.1, writer.field(2));
1215        })
1216    }
1217
1218    fn compute_field_size(item: &mut (T, U), sizer: FieldSizer<'_>) {
1219        sizer.message(|mut sizer| {
1220            E::compute_field_size(&mut item.0, sizer.field(1));
1221            F::compute_field_size(&mut item.1, sizer.field(2));
1222        })
1223    }
1224}
1225
1226impl<'a, T, U, E, F, R> FieldDecode<'a, (T, U), R> for PairEncoder<E, F>
1227where
1228    E: FieldDecode<'a, T, R>,
1229    F: FieldDecode<'a, U, R>,
1230{
1231    fn read_field(
1232        item: &mut InplaceOption<'_, (T, U)>,
1233        reader: FieldReader<'a, '_, R>,
1234    ) -> Result<()> {
1235        inplace_none!(t);
1236        inplace_none!(u);
1237        for field in reader.message()? {
1238            let (number, reader) = field?;
1239            match number {
1240                1 => {
1241                    E::read_field(&mut t, reader)?;
1242                }
1243                2 => {
1244                    F::read_field(&mut u, reader)?;
1245                }
1246                _ => {}
1247            }
1248        }
1249        if t.is_none() {
1250            E::default_field(&mut t)?;
1251        }
1252        if u.is_none() {
1253            F::default_field(&mut u)?;
1254        }
1255        item.set((t.take().unwrap(), u.take().unwrap()));
1256        Ok(())
1257    }
1258
1259    fn default_field(item: &mut InplaceOption<'_, (T, U)>) -> Result<()> {
1260        inplace_none!(t);
1261        E::default_field(&mut t)?;
1262        inplace_none!(u);
1263        F::default_field(&mut u)?;
1264        item.set((t.take().unwrap(), u.take().unwrap()));
1265        Ok(())
1266    }
1267}
1268
1269impl<K, V, T, EK, EV, R> FieldEncode<T, R> for MapField<K, V, EK, EV>
1270where
1271    T: IntoIterator<Item = (K, V)>,
1272    for<'a> &'a mut T: IntoIterator<Item = (&'a K, &'a mut V)>,
1273    for<'a> EK: FieldEncode<&'a K, R>,
1274    EV: FieldEncode<V, R>,
1275{
1276    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
1277        let mut writer = writer.sequence();
1278        for (k, v) in item {
1279            PairEncoder::<EK, EV>::write_field_in_sequence((&k, v), &mut writer);
1280        }
1281    }
1282
1283    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
1284        let mut sizer = sizer.sequence();
1285        for (mut k, v) in item {
1286            sizer.field().message(|mut sizer| {
1287                EK::compute_field_size(&mut k, sizer.field(1));
1288                EV::compute_field_size(v, sizer.field(2));
1289            });
1290        }
1291    }
1292
1293    fn wrap_in_sequence() -> bool {
1294        true
1295    }
1296}
1297
1298impl<'a, K, V, T, EK, EV, R> FieldDecode<'a, T, R> for MapField<K, V, EK, EV>
1299where
1300    T: Default + Extend<(K, V)>,
1301    EK: FieldDecode<'a, K, R>,
1302    EV: FieldDecode<'a, V, R>,
1303{
1304    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
1305        inplace_none!(v);
1306        PairEncoder::<EK, EV>::read_field(&mut v, reader)?;
1307        item.get_or_insert_with(Default::default).extend(v.take());
1308        Ok(())
1309    }
1310
1311    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
1312        item.get_or_insert_with(Default::default);
1313        Ok(())
1314    }
1315
1316    fn wrap_in_sequence() -> bool {
1317        true
1318    }
1319}
1320
1321/// A field encoder for fields that should be ignored.
1322pub struct IgnoreField;
1323
1324impl<T: Default, R> FieldEncode<T, R> for IgnoreField {
1325    fn write_field(_item: T, writer: FieldWriter<'_, '_, R>) {
1326        // No-op if not in a sequence.
1327        writer.message(|_| ());
1328    }
1329
1330    fn compute_field_size(_item: &mut T, sizer: FieldSizer<'_>) {
1331        // No-op if not in a sequence.
1332        sizer.message(|_| ());
1333    }
1334}
1335
1336impl<T: Default, R> FieldDecode<'_, T, R> for IgnoreField {
1337    fn read_field(_item: &mut InplaceOption<'_, T>, _reader: FieldReader<'_, '_, R>) -> Result<()> {
1338        Ok(())
1339    }
1340
1341    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
1342        item.set(Default::default());
1343        Ok(())
1344    }
1345}
1346
1347/// A field and message encoder for fields that cannot be instantiated.
1348pub struct ImpossibleField;
1349
1350impl<T> DescribeMessage<T> for ImpossibleField {
1351    const DESCRIPTION: MessageDescription<'static> = MessageDescription::External {
1352        name: "google.protobuf.Empty",
1353        import_path: "google/protobuf/empty.proto",
1354    };
1355}
1356
1357impl<T, R> FieldEncode<T, R> for ImpossibleField {
1358    fn write_field(_item: T, _writer: FieldWriter<'_, '_, R>) {
1359        unreachable!()
1360    }
1361
1362    fn compute_field_size(_item: &mut T, _sizer: FieldSizer<'_>) {
1363        unreachable!()
1364    }
1365}
1366
1367impl<T, R> FieldDecode<'_, T, R> for ImpossibleField {
1368    fn read_field(_item: &mut InplaceOption<'_, T>, _reader: FieldReader<'_, '_, R>) -> Result<()> {
1369        Err(DecodeError::Unexpected.into())
1370    }
1371
1372    fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<()> {
1373        Err(DecodeError::Unexpected.into())
1374    }
1375}
1376
1377impl<T, R> MessageEncode<T, R> for ImpossibleField {
1378    fn write_message(_item: T, _writer: MessageWriter<'_, '_, R>) {
1379        unreachable!()
1380    }
1381
1382    fn compute_message_size(_item: &mut T, _sizer: MessageSizer<'_>) {
1383        unreachable!()
1384    }
1385}
1386
1387impl<T, R> MessageDecode<'_, T, R> for ImpossibleField {
1388    fn read_message(
1389        _item: &mut InplaceOption<'_, T>,
1390        _reader: MessageReader<'_, '_, R>,
1391    ) -> Result<()> {
1392        Err(DecodeError::Unexpected.into())
1393    }
1394}
1395
1396/// A field encoder for fixed-sized arrays.
1397pub struct ArrayField<E>(E);
1398
1399impl<T, E: DescribeField<T>, const N: usize> DescribeField<[T; N]> for ArrayField<E> {
1400    const FIELD_TYPE: FieldType<'static> = {
1401        if let Some(packed) = E::PACKED_TYPE {
1402            FieldType::builtin(packed)
1403        } else if E::FIELD_TYPE.can_pack() {
1404            // BUGBUG: this is not protobuf compatible because protobuf allows
1405            // the unpacked encoding, which is not supported by `ArrayField`.
1406            // Change this once existing users are updated to use a different
1407            // type with a compatible encoding.
1408            E::FIELD_TYPE.repeated().annotate("packed repr only")
1409        } else {
1410            // Wrap in a message.
1411            FieldType::tuple(
1412                const {
1413                    if E::FIELD_TYPE.is_sequence() {
1414                        &[FieldType::tuple(&[E::FIELD_TYPE]).repeated()]
1415                    } else {
1416                        &[E::FIELD_TYPE.repeated()]
1417                    }
1418                },
1419            )
1420        }
1421    };
1422}
1423
1424impl<T, R, E: FieldEncode<T, R>, const N: usize> FieldEncode<[T; N], R> for ArrayField<E> {
1425    fn write_field(item: [T; N], writer: FieldWriter<'_, '_, R>) {
1426        if let Some(packed_encode) = E::packed() {
1427            writer.packed(|packed| packed_encode.write_packed(&item, packed));
1428        } else {
1429            // The fixed array has to be wrapped in an object to support
1430            // reading.
1431            writer.message(|mut message| {
1432                let mut writer = message.field(1).sequence();
1433                for v in item {
1434                    E::write_field_in_sequence(v, &mut writer);
1435                }
1436            });
1437        }
1438    }
1439
1440    fn compute_field_size(item: &mut [T; N], sizer: FieldSizer<'_>) {
1441        if let Some(packed_encode) = E::packed() {
1442            sizer.packed(|packed| packed_encode.compute_packed_size(item, packed));
1443        } else {
1444            sizer.message(|mut message| {
1445                let mut sizer = message.field(1).sequence();
1446                for v in item {
1447                    E::compute_field_size_in_sequence(v, &mut sizer);
1448                }
1449            });
1450        }
1451    }
1452}
1453
1454impl<'a, T, R, E: FieldDecode<'a, T, R>, const N: usize> FieldDecode<'a, [T; N], R>
1455    for ArrayField<E>
1456{
1457    fn read_field(
1458        item: &mut InplaceOption<'_, [T; N]>,
1459        reader: FieldReader<'a, '_, R>,
1460    ) -> Result<()> {
1461        if let Some(packed_decode) = E::packed() {
1462            let mut vec = Vec::with_capacity(N); // TODO: use an in-place mechanism
1463            packed_decode.read_packed(&mut vec, &mut reader.packed()?)?;
1464            item.set(
1465                vec.try_into()
1466                    .map_err(|_| DecodeError::BadPackedArrayLength)?,
1467            );
1468        } else {
1469            let vec = Vec::with_capacity(N); // TODO: use an in-place mechanism
1470            inplace_some!(vec);
1471            VecField::<E>::read_field_in_sequence(&mut vec, reader)?;
1472            item.set(
1473                vec.take()
1474                    .expect("should still be set")
1475                    .try_into()
1476                    .map_err(|_| DecodeError::BadArrayLength)?,
1477            );
1478        }
1479        Ok(())
1480    }
1481
1482    fn default_field(_item: &mut InplaceOption<'_, [T; N]>) -> Result<()> {
1483        // TODO
1484        Err(DecodeError::MissingRequiredField.into())
1485    }
1486}
1487
1488/// A field encoding for C-format structs.
1489///
1490/// Messages will be encoded as `bytes` fields whose size must exactly match the
1491/// struct's size.
1492///
1493/// Missing fields will be zero-initialized during message decode.
1494pub struct ZeroCopyEncoding;
1495
1496impl<T> DescribeField<T> for ZeroCopyEncoding {
1497    const FIELD_TYPE: FieldType<'static> = FieldType::builtin("bytes");
1498}
1499
1500#[derive(Debug, Error)]
1501#[error("invalid byte size for type")]
1502struct InvalidZeroCopySize;
1503
1504impl<T: zerocopy::IntoBytes + Immutable + KnownLayout, R> FieldEncode<T, R> for ZeroCopyEncoding {
1505    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
1506        writer.bytes(item.as_bytes());
1507    }
1508
1509    fn compute_field_size(item: &mut T, sizer: FieldSizer<'_>) {
1510        sizer.bytes(item.as_bytes().len());
1511    }
1512}
1513
1514impl<'a, T: zerocopy::FromBytes + Immutable + KnownLayout, R> FieldDecode<'a, T, R>
1515    for ZeroCopyEncoding
1516{
1517    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'a, '_, R>) -> Result<()> {
1518        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)
1519        Ok(())
1520    }
1521
1522    fn default_field(item: &mut InplaceOption<'_, T>) -> Result<()> {
1523        item.set(T::new_zeroed());
1524        Ok(())
1525    }
1526}
1527
1528/// A wrapper encoding for boxed data.
1529///
1530/// Messages and fields are handled as if they are not boxed, except that they
1531/// are never encoded in packed format.
1532pub struct BoxEncoding<E>(E);
1533
1534impl<E: DescribeField<T>, T> DescribeField<T> for BoxEncoding<E> {
1535    const FIELD_TYPE: FieldType<'static> = E::FIELD_TYPE;
1536}
1537
1538impl<E: DescribeMessage<T>, T> DescribeMessage<T> for BoxEncoding<E> {
1539    const DESCRIPTION: MessageDescription<'static> = E::DESCRIPTION;
1540}
1541
1542impl<T, R, E: MessageEncode<T, R>> MessageEncode<Box<T>, R> for BoxEncoding<E> {
1543    fn write_message(item: Box<T>, writer: MessageWriter<'_, '_, R>) {
1544        E::write_message(*item, writer)
1545    }
1546
1547    fn compute_message_size(item: &mut Box<T>, sizer: MessageSizer<'_>) {
1548        E::compute_message_size(&mut *item, sizer)
1549    }
1550}
1551
1552impl<'a, T, R, E: MessageDecode<'a, T, R>> MessageDecode<'a, Box<T>, R> for BoxEncoding<E> {
1553    fn read_message(
1554        item: &mut InplaceOption<'_, Box<T>>,
1555        reader: MessageReader<'a, '_, R>,
1556    ) -> Result<()> {
1557        item.update_box(|item| E::read_message(item, reader))
1558    }
1559}
1560
1561impl<T, R, E: FieldEncode<T, R>> FieldEncode<Box<T>, R> for BoxEncoding<E> {
1562    fn write_field(item: Box<T>, writer: FieldWriter<'_, '_, R>) {
1563        E::write_field(*item, writer)
1564    }
1565
1566    fn compute_field_size(item: &mut Box<T>, sizer: FieldSizer<'_>) {
1567        E::compute_field_size(&mut *item, sizer)
1568    }
1569
1570    fn wrap_in_sequence() -> bool {
1571        E::wrap_in_sequence()
1572    }
1573}
1574
1575impl<'a, T, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Box<T>, R> for BoxEncoding<E> {
1576    fn read_field(
1577        item: &mut InplaceOption<'_, Box<T>>,
1578        reader: FieldReader<'a, '_, R>,
1579    ) -> Result<()> {
1580        item.update_box(|item| E::read_field(item, reader))
1581    }
1582
1583    fn default_field(item: &mut InplaceOption<'_, Box<T>>) -> Result<()> {
1584        item.update_box(|item| E::default_field(item))
1585    }
1586
1587    fn wrap_in_sequence() -> bool {
1588        E::wrap_in_sequence()
1589    }
1590}
1591
1592/// A wrapper encoding for reference-counted data.
1593///
1594/// If the `Arc<T>` is the sole owner of T, then T is serialized as-is. If there
1595/// are other references, then the T is first cloned so that there is a single
1596/// instance.
1597///
1598/// Messages and fields are handled as if they are not reference counted, except
1599/// that they are never encoded in packed format.
1600pub struct ArcEncoding<E>(E);
1601
1602impl<E: DescribeField<T>, T> DescribeField<T> for ArcEncoding<E> {
1603    const FIELD_TYPE: FieldType<'static> = E::FIELD_TYPE;
1604}
1605
1606impl<E: DescribeMessage<T>, T> DescribeMessage<T> for ArcEncoding<E> {
1607    const DESCRIPTION: MessageDescription<'static> = E::DESCRIPTION;
1608}
1609
1610impl<T: Clone, R, E: MessageEncode<T, R>> MessageEncode<Arc<T>, R> for ArcEncoding<E> {
1611    fn write_message(item: Arc<T>, writer: MessageWriter<'_, '_, R>) {
1612        E::write_message(
1613            Arc::try_unwrap(item)
1614                .ok()
1615                .expect("compute_message_size ensured single instance"),
1616            writer,
1617        )
1618    }
1619
1620    fn compute_message_size(item: &mut Arc<T>, sizer: MessageSizer<'_>) {
1621        E::compute_message_size(Arc::make_mut(item), sizer)
1622    }
1623}
1624
1625impl<'a, T: Clone, R, E: MessageDecode<'a, T, R>> MessageDecode<'a, Arc<T>, R> for ArcEncoding<E> {
1626    fn read_message(
1627        item: &mut InplaceOption<'_, Arc<T>>,
1628        reader: MessageReader<'a, '_, R>,
1629    ) -> Result<()> {
1630        item.update_arc(|item| E::read_message(item, reader))
1631    }
1632}
1633
1634impl<T: Clone, R, E: FieldEncode<T, R>> FieldEncode<Arc<T>, R> for ArcEncoding<E> {
1635    fn write_field(item: Arc<T>, writer: FieldWriter<'_, '_, R>) {
1636        E::write_field(
1637            Arc::try_unwrap(item)
1638                .ok()
1639                .expect("compute_field_size ensured single instance"),
1640            writer,
1641        )
1642    }
1643
1644    fn compute_field_size(item: &mut Arc<T>, sizer: FieldSizer<'_>) {
1645        E::compute_field_size(Arc::make_mut(item), sizer)
1646    }
1647
1648    fn wrap_in_sequence() -> bool {
1649        E::wrap_in_sequence()
1650    }
1651}
1652
1653impl<'a, T: Clone, R, E: FieldDecode<'a, T, R>> FieldDecode<'a, Arc<T>, R> for ArcEncoding<E> {
1654    fn read_field(
1655        item: &mut InplaceOption<'_, Arc<T>>,
1656        reader: FieldReader<'a, '_, R>,
1657    ) -> Result<()> {
1658        item.update_arc(|item| E::read_field(item, reader))
1659    }
1660
1661    fn default_field(item: &mut InplaceOption<'_, Arc<T>>) -> Result<()> {
1662        item.update_arc(|item| E::default_field(item))
1663    }
1664
1665    fn wrap_in_sequence() -> bool {
1666        E::wrap_in_sequence()
1667    }
1668}
1669
1670macro_rules! default_encodings {
1671    ($($(#[$attr:meta])* $ty:ty: $mp:ty),* $(,)?) => {
1672        $(
1673            $(
1674                #[$attr]
1675            )*
1676            impl $crate::DefaultEncoding for $ty {
1677                type Encoding = $mp;
1678            }
1679        )*
1680    };
1681}
1682
1683// Set the default encodings for common Rust types.
1684default_encodings! {
1685    u8: ByteField,
1686    u16: VarintField,
1687    u32: VarintField,
1688    u64: VarintField,
1689    u128: U128LittleEndianField,
1690    Wrapping<u64>: VarintField,
1691    usize: VarintField,
1692    bool: VarintField,
1693    char: VarintField,
1694
1695    i8: SignedVarintField,
1696    i16: SignedVarintField,
1697    i32: SignedVarintField,
1698    i64: SignedVarintField,
1699    isize: SignedVarintField,
1700
1701    f64: Fixed64Field,
1702    f32: Fixed32Field,
1703
1704    NonZeroU8: VarintField,
1705    NonZeroU16: VarintField,
1706    NonZeroU32: VarintField,
1707    NonZeroU64: VarintField,
1708    NonZeroUsize: VarintField,
1709    NonZeroI8: SignedVarintField,
1710    NonZeroI16: SignedVarintField,
1711    NonZeroI32: SignedVarintField,
1712    NonZeroI64: SignedVarintField,
1713    NonZeroIsize: SignedVarintField,
1714
1715    String: StringField,
1716
1717    Duration: MessageEncoding<DurationEncoding>,
1718
1719    Infallible: ImpossibleField,
1720
1721    core::net::Ipv4Addr: Fixed32Field,
1722    core::net::Ipv6Addr: Ipv6AddrField,
1723}
1724
1725impl DefaultEncoding for &str {
1726    type Encoding = StringField;
1727}
1728
1729impl DefaultEncoding for &[u8] {
1730    type Encoding = BytesField;
1731}
1732
1733impl DefaultEncoding for Cow<'_, str> {
1734    type Encoding = StringField;
1735}
1736
1737impl<T: DefaultEncoding> DefaultEncoding for Option<T> {
1738    type Encoding = OptionField<T::Encoding>;
1739}
1740
1741impl<T: DefaultEncoding> DefaultEncoding for Vec<T> {
1742    type Encoding = VecField<T::Encoding>;
1743}
1744
1745#[cfg(feature = "std")]
1746impl<K: DefaultEncoding, V: DefaultEncoding> DefaultEncoding for std::collections::HashMap<K, V> {
1747    type Encoding = MapField<K, V, K::Encoding, V::Encoding>;
1748}
1749
1750impl<K: DefaultEncoding, V: DefaultEncoding> DefaultEncoding for BTreeMap<K, V> {
1751    type Encoding = MapField<K, V, K::Encoding, V::Encoding>;
1752}
1753
1754impl<T> DefaultEncoding for PhantomData<T> {
1755    type Encoding = IgnoreField;
1756}
1757
1758impl<T: DefaultEncoding, const N: usize> DefaultEncoding for [T; N] {
1759    type Encoding = ArrayField<T::Encoding>;
1760}
1761
1762impl<T: DefaultEncoding> DefaultEncoding for Box<T> {
1763    type Encoding = BoxEncoding<T::Encoding>;
1764}
1765
1766impl<T: DefaultEncoding + Clone> DefaultEncoding for Arc<T> {
1767    type Encoding = ArcEncoding<T::Encoding>;
1768}
1769
1770// Derive an encoding for `Result`.
1771#[derive(mesh_derive::Protobuf)]
1772#[mesh(impl_for = "::core::result::Result")]
1773#[expect(dead_code)]
1774enum ResultAsPayload<T, U> {
1775    #[mesh(transparent)]
1776    Ok(T),
1777    #[mesh(transparent)]
1778    Err(U),
1779}
1780
1781// Derive an encoding for `Range`.
1782#[derive(mesh_derive::Protobuf)]
1783#[mesh(impl_for = "::core::ops::Range")]
1784#[expect(dead_code)]
1785struct RangeAsPayload<T> {
1786    start: T,
1787    end: T,
1788}
1789
1790/// An encoder for [`SerializedMessage`].
1791pub struct SerializedMessageEncoder;
1792
1793impl<R> MessageEncode<SerializedMessage<R>, R> for SerializedMessageEncoder {
1794    fn write_message(item: SerializedMessage<R>, mut writer: MessageWriter<'_, '_, R>) {
1795        writer.raw_message(&item.data, item.resources);
1796    }
1797
1798    fn compute_message_size(item: &mut SerializedMessage<R>, mut sizer: MessageSizer<'_>) {
1799        sizer.raw_message(item.data.len(), item.resources.len() as u32);
1800    }
1801}
1802
1803impl<R> MessageDecode<'_, SerializedMessage<R>, R> for SerializedMessageEncoder {
1804    fn read_message(
1805        item: &mut InplaceOption<'_, SerializedMessage<R>>,
1806        mut reader: MessageReader<'_, '_, R>,
1807    ) -> Result<()> {
1808        let resources = reader.take_resources();
1809        match item.as_mut() {
1810            Some(message) => {
1811                // Protobuf messages are merged just by adding in the extra
1812                // fields to the end. This works even with ports and resources
1813                // present.
1814                message.data.extend(reader.bytes());
1815                for resource in reader.take_resources() {
1816                    message.resources.push(resource?);
1817                }
1818            }
1819            None => {
1820                item.set(SerializedMessage {
1821                    data: reader.bytes().to_vec(),
1822                    resources: resources.collect::<Result<_>>()?,
1823                });
1824            }
1825        }
1826        Ok(())
1827    }
1828}
1829
1830impl<R> DefaultEncoding for SerializedMessage<R> {
1831    type Encoding = MessageEncoding<SerializedMessageEncoder>;
1832}
1833
1834/// A field encoder for types that can be converted to and from OS resource type
1835/// `T`.
1836pub struct ResourceField<T>(PhantomData<T>);
1837
1838impl<T> Default for ResourceField<T> {
1839    fn default() -> Self {
1840        Self(PhantomData)
1841    }
1842}
1843
1844impl<T, U, R> FieldEncode<T, R> for ResourceField<U>
1845where
1846    T: Into<U>,
1847    U: Into<R>,
1848{
1849    fn write_field(item: T, writer: FieldWriter<'_, '_, R>) {
1850        writer.resource(item.into().into());
1851    }
1852
1853    fn compute_field_size(_item: &mut T, sizer: FieldSizer<'_>) {
1854        sizer.resource();
1855    }
1856}
1857
1858impl<T, U, R> FieldDecode<'_, T, R> for ResourceField<U>
1859where
1860    T: From<U>,
1861    U: TryFrom<R>,
1862    U::Error: 'static + core::error::Error + Send + Sync,
1863{
1864    fn read_field(item: &mut InplaceOption<'_, T>, reader: FieldReader<'_, '_, R>) -> Result<()> {
1865        let resource = T::from(reader.resource()?.try_into().map_err(Error::new)?);
1866        item.set(resource);
1867        Ok(())
1868    }
1869
1870    fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<()> {
1871        Err(DecodeError::MissingResource.into())
1872    }
1873}
1874
1875/// Implements [`DefaultEncoding`] for OS resources.
1876///
1877/// The specified type must implement `From<R>` and `Into<R>`, where `R` is the
1878/// underlying OS resource type (such as `OwnedFd` or `OwnedHandle`).
1879#[macro_export]
1880macro_rules! os_resource {
1881    ($ty:ty, $resource_ty:ty) => {
1882        impl $crate::DefaultEncoding for $ty {
1883            type Encoding = $crate::encoding::ResourceField<$resource_ty>;
1884        }
1885    };
1886}
1887
1888#[cfg(all(feature = "std", windows))]
1889mod windows {
1890    use crate::os_resource;
1891    use std::os::windows::prelude::*;
1892
1893    os_resource!(OwnedHandle, OwnedHandle);
1894    os_resource!(std::fs::File, OwnedHandle);
1895
1896    os_resource!(OwnedSocket, OwnedSocket);
1897    os_resource!(std::net::TcpListener, OwnedSocket);
1898    os_resource!(std::net::TcpStream, OwnedSocket);
1899    os_resource!(std::net::UdpSocket, OwnedSocket);
1900
1901    #[cfg(feature = "socket2")]
1902    os_resource!(socket2::Socket, OwnedSocket);
1903}
1904
1905#[cfg(all(feature = "std", unix))]
1906mod unix {
1907    use crate::os_resource;
1908    use std::os::unix::prelude::*;
1909
1910    os_resource!(OwnedFd, OwnedFd);
1911    os_resource!(std::fs::File, OwnedFd);
1912    os_resource!(std::os::unix::net::UnixListener, OwnedFd);
1913    os_resource!(std::os::unix::net::UnixStream, OwnedFd);
1914    os_resource!(std::net::TcpListener, OwnedFd);
1915    os_resource!(std::net::TcpStream, OwnedFd);
1916    os_resource!(std::net::UdpSocket, OwnedFd);
1917
1918    #[cfg(feature = "socket2")]
1919    os_resource!(socket2::Socket, OwnedFd);
1920}