protokit_binformat/
lib.rs

1#![allow(clippy::ptr_arg)]
2#![deny(unconditional_recursion)]
3
4use core::fmt::Debug;
5use core::hash::Hash;
6use core::ops::{Deref, DerefMut};
7use core::str::Utf8Error;
8use std::borrow::Cow;
9use std::collections::BTreeMap;
10use std::string::FromUtf8Error;
11
12use bytes::Bytes;
13use indexmap::IndexMap;
14pub use stream::{InputStream, OutputStream};
15use thiserror::Error;
16pub use value::{Field, UnknownFieldsBorrow, UnknownFieldsOwned, Value};
17
18pub mod stream;
19pub mod value;
20
21pub const MASK_WIRE: u8 = 0b111;
22
23pub const VARINT: u8 = 0;
24pub const FIX64: u8 = 1;
25pub const BYTES: u8 = 2;
26pub const SGRP: u8 = 3;
27pub const EGRP: u8 = 4;
28pub const FIX32: u8 = 5;
29
30#[repr(u8)]
31#[derive(Debug, Error)]
32pub enum Error {
33    #[error("Unexpected end of input")]
34    UnexpectedEOF,
35
36    #[error("Length of submessage exceeds the length of message")]
37    InvalidBytesLimit,
38
39    #[error("String is not UTF8: {0}")]
40    InvalidUtf8(#[from] Utf8Error),
41
42    #[error("String is not UTF8: {0}")]
43    InvalidFromUtf8(#[from] FromUtf8Error),
44
45    #[error("Unterminated group")]
46    UnterminatedGroup,
47
48    #[error("Unknown tag: {0}")]
49    UnknownTag(u32),
50
51    #[error("Unknown wire type: {0}")]
52    UnknownWire(u8),
53}
54
55pub type Result<T, E = Error> = core::result::Result<T, E>;
56
57#[cold]
58pub fn unknown_tag<T>(tag: u32) -> Result<T> {
59    Err(Error::UnknownTag(tag))
60}
61
62#[cold]
63pub fn unknown_wire<T>(w: u8) -> Result<T> {
64    Err(Error::UnknownWire(w))
65}
66
67pub trait BinProto<'buf> {
68    fn qualified_name(&self) -> &'static str;
69    fn merge_field(&mut self, tag_wire: u32, stream: &mut InputStream<'buf>) -> Result<()>;
70    fn size(&self, stack: &mut SizeStack) -> usize;
71    fn encode(&self, stream: &mut OutputStream);
72}
73
74impl<'buf, T> BinProto<'buf> for Box<T>
75where
76    T: BinProto<'buf>,
77{
78    #[inline(always)]
79    fn qualified_name(&self) -> &'static str {
80        self.deref().qualified_name()
81    }
82
83    #[inline(always)]
84    fn merge_field(&mut self, tag_wire: u32, stream: &mut InputStream<'buf>) -> Result<()> {
85        self.deref_mut().merge_field(tag_wire, stream)
86    }
87
88    #[inline(always)]
89    fn size(&self, stack: &mut SizeStack) -> usize {
90        self.deref().size(stack)
91    }
92
93    #[inline(always)]
94    fn encode(&self, stream: &mut OutputStream) {
95        self.deref().encode(stream)
96    }
97}
98
99#[cfg(feature = "arena")]
100impl<'buf, 'arena, T> BinProto<'buf> for bumpalo::boxed::Box<'arena, T>
101where
102    T: BinProto<'buf>,
103{
104    fn qualified_name(&self) -> &'static str {
105        self.deref().qualified_name()
106    }
107
108    fn merge_field(&mut self, tag_wire: u32, stream: &mut InputStream<'buf>) -> Result<()> {
109        self.deref_mut().merge_field(tag_wire, stream)
110    }
111
112    fn size(&self, stack: &mut SizeStack) -> usize {
113        self.deref().size(stack)
114    }
115
116    fn encode(&self, stream: &mut OutputStream) {
117        self.deref().encode(stream)
118    }
119}
120
121pub trait Varint: Default + Debug + Clone + Copy {
122    fn from_u64(v: u64) -> Self;
123    fn into_u64(self) -> u64;
124}
125
126macro_rules! impl_varint {
127    ($($ty:ty),*) => {$(
128        impl Varint for $ty {
129            #[inline(always)]
130            fn from_u64(v: u64) -> Self {
131                v as _
132            }
133            #[inline(always)]
134            fn into_u64(self) -> u64 {
135                self as _
136            }
137        })*
138    };
139}
140
141impl_varint!(i32, u32, i64, u64, usize);
142
143pub trait Sigint: Default + Clone + Copy {
144    type Varint: Varint;
145    fn encode(self) -> Self::Varint;
146    fn decode(from: Self::Varint) -> Self;
147}
148
149impl Sigint for i32 {
150    type Varint = u32;
151    fn encode(self) -> Self::Varint {
152        ((self << 1) ^ (self >> 31)) as u32
153    }
154
155    fn decode(from: Self::Varint) -> Self {
156        ((from >> 1) ^ (-((from & 1) as i32)) as u32) as i32
157    }
158}
159
160impl Sigint for i64 {
161    type Varint = u64;
162    fn encode(self) -> Self::Varint {
163        ((self << 1) ^ (self >> 63)) as u64
164    }
165
166    fn decode(from: Self::Varint) -> Self {
167        ((from >> 1) ^ (-((from & 1) as i64)) as u64) as i64
168    }
169}
170
171pub trait Fixed: Default + Sized + Clone + Copy {
172    type Wire: Sized;
173    fn from_wire(v: Self::Wire) -> Self;
174    fn to_wire(self) -> Self::Wire;
175}
176
177impl Fixed for i32 {
178    type Wire = u32;
179
180    #[inline(always)]
181    fn from_wire(v: Self::Wire) -> Self {
182        Self::from_le(v as _)
183    }
184
185    #[inline(always)]
186    fn to_wire(self) -> Self::Wire {
187        self.to_le() as _
188    }
189}
190
191impl Fixed for i64 {
192    type Wire = u64;
193
194    #[inline(always)]
195    fn from_wire(v: Self::Wire) -> Self {
196        Self::from_le(v as _)
197    }
198
199    #[inline(always)]
200    fn to_wire(self) -> Self::Wire {
201        self.to_le() as _
202    }
203}
204
205impl Fixed for u32 {
206    type Wire = u32;
207
208    #[inline(always)]
209    fn from_wire(v: Self::Wire) -> Self {
210        Self::from_le(v)
211    }
212
213    #[inline(always)]
214    fn to_wire(self) -> Self::Wire {
215        self.to_le()
216    }
217}
218
219impl Fixed for u64 {
220    type Wire = Self;
221
222    #[inline(always)]
223    fn from_wire(v: Self::Wire) -> Self {
224        Self::from_le(v)
225    }
226
227    #[inline(always)]
228    fn to_wire(self) -> Self::Wire {
229        self.to_le()
230    }
231}
232
233impl Fixed for f32 {
234    type Wire = u32;
235
236    #[inline(always)]
237    fn from_wire(v: Self::Wire) -> Self {
238        Self::from_bits(Self::Wire::from_le(v))
239    }
240
241    #[inline(always)]
242    fn to_wire(self) -> Self::Wire {
243        self.to_bits().to_le()
244    }
245}
246
247impl Fixed for f64 {
248    type Wire = u64;
249
250    #[inline(always)]
251    fn from_wire(v: Self::Wire) -> Self {
252        Self::from_bits(Self::Wire::from_le(v))
253    }
254
255    #[inline(always)]
256    fn to_wire(self) -> Self::Wire {
257        self.to_bits().to_le()
258    }
259}
260
261pub trait BytesLike<'a>: Debug + Default {
262    /// Length of this field
263    fn len(&self) -> usize;
264    /// Reference to underlying byte byffer
265    fn buf(&self) -> &[u8];
266    /// Set this byte buffer to new value
267    fn set(&mut self, b: &'a [u8]) -> Result<()>;
268    fn set_bytes(&mut self, b: Bytes) -> Result<()>;
269}
270
271impl<'buf> BytesLike<'buf> for &'buf str {
272    #[inline(always)]
273    fn len(&self) -> usize {
274        str::len(self)
275    }
276
277    #[inline(always)]
278    fn buf(&self) -> &[u8] {
279        self.as_bytes()
280    }
281
282    #[inline(always)]
283    fn set(&mut self, b: &'buf [u8]) -> Result<()> {
284        *self = core::str::from_utf8(b)?;
285        Ok(())
286    }
287
288    fn set_bytes(&mut self, _: Bytes) -> Result<()> {
289        panic!("Can't set from bytes")
290    }
291}
292
293impl<'buf> BytesLike<'buf> for String {
294    #[inline(always)]
295    fn len(&self) -> usize {
296        self.len()
297    }
298
299    #[inline(always)]
300    fn buf(&self) -> &[u8] {
301        self.as_bytes()
302    }
303
304    #[inline(always)]
305    fn set(&mut self, b: &[u8]) -> Result<()> {
306        self.clear();
307        self.push_str(core::str::from_utf8(b)?);
308        Ok(())
309    }
310
311    fn set_bytes(&mut self, b: Bytes) -> Result<()> {
312        self.clear();
313        self.push_str(core::str::from_utf8(&b)?);
314        Ok(())
315    }
316}
317
318impl<'buf> BytesLike<'buf> for Cow<'buf, str> {
319    fn len(&self) -> usize {
320        str::len(self)
321    }
322
323    fn buf(&self) -> &[u8] {
324        self.as_bytes()
325    }
326
327    fn set(&mut self, b: &'buf [u8]) -> Result<()> {
328        let b = std::str::from_utf8(b)?;
329        *self = Cow::Borrowed(b);
330        Ok(())
331    }
332
333    fn set_bytes(&mut self, b: Bytes) -> Result<()> {
334        *self = Cow::Owned(String::from_utf8(b.to_vec())?);
335        Ok(())
336    }
337}
338
339impl<'buf> BytesLike<'buf> for &'buf [u8] {
340    #[inline(always)]
341    fn len(&self) -> usize {
342        <[u8]>::len(self)
343    }
344
345    #[inline(always)]
346    fn buf(&self) -> &[u8] {
347        self
348    }
349
350    #[inline(always)]
351    fn set(&mut self, b: &'buf [u8]) -> Result<()> {
352        *self = b;
353        Ok(())
354    }
355
356    fn set_bytes(&mut self, _: Bytes) -> Result<()> {
357        panic!("Can't borrow from bytes")
358    }
359}
360
361impl<'buf> BytesLike<'buf> for Vec<u8> {
362    #[inline(always)]
363    fn len(&self) -> usize {
364        self.len()
365    }
366
367    #[inline(always)]
368    fn buf(&self) -> &[u8] {
369        self.as_slice()
370    }
371
372    #[inline(always)]
373    fn set(&mut self, b: &[u8]) -> Result<()> {
374        self.clear();
375        self.extend_from_slice(b);
376        Ok(())
377    }
378
379    fn set_bytes(&mut self, b: Bytes) -> Result<()> {
380        self.clear();
381        self.extend_from_slice(&b);
382        Ok(())
383    }
384}
385
386impl<'buf> BytesLike<'buf> for Cow<'buf, [u8]> {
387    #[inline(always)]
388    fn len(&self) -> usize {
389        <[u8]>::len(self)
390    }
391
392    #[inline(always)]
393    fn buf(&self) -> &[u8] {
394        self
395    }
396
397    #[inline(always)]
398    fn set(&mut self, b: &'buf [u8]) -> Result<()> {
399        *self = Cow::Borrowed(b);
400        Ok(())
401    }
402
403    #[inline(always)]
404    fn set_bytes(&mut self, b: Bytes) -> Result<()> {
405        *self = Cow::Owned(b.to_vec());
406        Ok(())
407    }
408}
409
410impl<'a, const N: usize> BytesLike<'a> for [u8; N]
411where
412    [u8; N]: Default,
413{
414    fn len(&self) -> usize {
415        N
416    }
417
418    fn buf(&self) -> &[u8] {
419        self
420    }
421
422    fn set(&mut self, b: &'a [u8]) -> Result<()> {
423        *self = b.try_into().map_err(|_| Error::InvalidBytesLimit)?;
424        Ok(())
425    }
426
427    fn set_bytes(&mut self, b: Bytes) -> Result<()> {
428        self.set(&b)
429    }
430}
431
432impl<'a> BytesLike<'a> for Bytes {
433    fn len(&self) -> usize {
434        Bytes::len(self)
435    }
436
437    fn buf(&self) -> &[u8] {
438        Bytes::deref(self)
439    }
440
441    fn set(&mut self, b: &'a [u8]) -> Result<()> {
442        *self = Bytes::from(b.to_vec());
443        Ok(())
444    }
445
446    fn set_bytes(&mut self, b: Bytes) -> Result<()> {
447        *self = b;
448        Ok(())
449    }
450}
451
452pub trait Map<K, V> {
453    fn mlen(&self) -> usize;
454    fn insert(&mut self, k: K, v: V);
455    fn for_each<F: FnMut((&K, &V))>(&self, fun: F);
456    fn rev_for_each<F: FnMut((&K, &V))>(&self, fun: F);
457}
458
459impl<K: PartialOrd + Ord + PartialEq, V> Map<K, V> for BTreeMap<K, V> {
460    fn mlen(&self) -> usize {
461        self.len()
462    }
463
464    fn insert(&mut self, k: K, v: V) {
465        let _ = self.insert(k, v);
466    }
467
468    fn for_each<F: FnMut((&K, &V))>(&self, fun: F) {
469        self.iter().for_each(fun)
470    }
471
472    fn rev_for_each<F: FnMut((&K, &V))>(&self, fun: F) {
473        self.iter().rev().for_each(fun)
474    }
475}
476
477impl<K: Hash + PartialEq + Eq, V> Map<K, V> for IndexMap<K, V> {
478    fn mlen(&self) -> usize {
479        self.len()
480    }
481
482    fn insert(&mut self, k: K, v: V) {
483        let _ = IndexMap::insert(self, k, v);
484    }
485
486    fn for_each<F: FnMut((&K, &V))>(&self, fun: F) {
487        self.iter().for_each(fun)
488    }
489
490    fn rev_for_each<F: FnMut((&K, &V))>(&self, fun: F) {
491        self.iter().rev().for_each(fun)
492    }
493}
494
495#[inline(never)]
496pub fn merge_single<'buf, T, F>(this: &mut T, stream: &mut InputStream<'buf>, mapper: F) -> Result<()>
497where
498    F: Fn(&mut InputStream<'buf>, &mut T) -> Result<()>,
499{
500    mapper(stream, this)
501}
502
503#[inline(never)]
504pub fn merge_optional<'buf, T, F>(this: &mut Option<T>, stream: &mut InputStream<'buf>, mapper: F) -> Result<()>
505where
506    T: Default,
507    F: Fn(&mut InputStream<'buf>, &mut T) -> Result<()>,
508{
509    mapper(stream, this.get_or_insert_with(Default::default))
510}
511
512#[inline(never)]
513pub fn merge_repeated<'buf, T, F>(this: &mut Vec<T>, stream: &mut InputStream<'buf>, mapper: F) -> Result<()>
514where
515    T: Default,
516    F: Fn(&mut InputStream<'buf>, &mut T) -> Result<()>,
517{
518    this.push(T::default());
519    unsafe { mapper(stream, this.last_mut().unwrap_unchecked()) }
520}
521
522#[inline(never)]
523pub fn merge_packed<'buf, T, F>(this: &mut Vec<T>, stream: &mut InputStream<'buf>, mapper: F) -> Result<()>
524where
525    T: Default,
526    F: Fn(&mut InputStream<'buf>, &mut T) -> Result<()>,
527{
528    this.clear();
529    let len = stream._varint::<usize>()?;
530    if stream.len() < len {
531        return Err(Error::UnexpectedEOF);
532    }
533    let mut is = InputStream {
534        buf: &stream.buf[stream.pos .. stream.pos + len],
535        pos: 0,
536        limit: len,
537    };
538    while !is.is_empty() {
539        this.push(T::default());
540        // Safe, we've just pushed an elem into this
541        unsafe {
542            mapper(&mut is, this.last_mut().unwrap_unchecked())?;
543        }
544    }
545    stream.pos += len;
546    Ok(())
547}
548
549#[inline(never)]
550pub fn merge_map<'buf, K, V, M: Map<K, V>>(
551    this: &mut M,
552    stream: &mut InputStream<'buf>,
553    kmapper: fn(&mut InputStream<'buf>, &mut K) -> Result<()>,
554    vmapper: fn(&mut InputStream<'buf>, &mut V) -> Result<()>,
555) -> Result<()>
556where
557    K: Default,
558    V: Default,
559{
560    let len = stream._varint::<usize>()?;
561    let olimit = stream.limit(len)?;
562
563    let mut key = K::default();
564    let mut val = V::default();
565    while !stream.is_empty() {
566        // TODO: verify wire types
567        match stream._varint::<u32>()? >> 3 {
568            1 => merge_single(&mut key, stream, kmapper)?,
569            2 => merge_single(&mut val, stream, vmapper)?,
570            tag => unknown_tag(tag)?,
571        }
572    }
573    this.insert(key, val);
574    stream.unlimit(olimit);
575    Ok(())
576}
577
578#[inline(never)]
579pub fn merge_oneof<'buf, T: Default + BinProto<'buf>>(
580    this: &mut Option<T>,
581    tag: u32,
582    stream: &mut InputStream<'buf>,
583) -> Result<()> {
584    this.get_or_insert_with(Default::default).merge_field(tag, stream)
585}
586
587#[inline(never)]
588pub fn emit_raw<T>(this: &T, tag: u32, stream: &mut OutputStream, mapper: fn(&mut OutputStream, u32, &T)) {
589    stream._tag(tag);
590    mapper(stream, tag, this);
591}
592
593#[inline(never)]
594pub fn emit_single<T: Default + PartialEq>(
595    this: &T,
596    tag: u32,
597    stream: &mut OutputStream,
598    mapper: fn(&mut OutputStream, u32, &T),
599) {
600    if this != &T::default() {
601        emit_raw(this, tag, stream, mapper)
602    }
603}
604
605#[inline(never)]
606pub fn emit_optional<T>(this: &Option<T>, tag: u32, stream: &mut OutputStream, mapper: fn(&mut OutputStream, u32, &T)) {
607    if let Some(v) = this {
608        stream._tag(tag);
609        mapper(stream, tag, v);
610    }
611}
612
613#[inline(never)]
614pub fn emit_repeated<T>(this: &Vec<T>, tag: u32, stream: &mut OutputStream, mapper: fn(&mut OutputStream, u32, &T)) {
615    for v in this {
616        stream._tag(tag);
617        mapper(stream, tag, v)
618    }
619}
620
621#[inline(never)]
622pub fn emit_packed<T>(this: &Vec<T>, tag: u32, stream: &mut OutputStream, mapper: fn(&mut OutputStream, u32, &T)) {
623    if !this.is_empty() {
624        stream._tag(tag);
625        let mut o = OutputStream::default();
626        for v in this {
627            mapper(&mut o, tag, v);
628        }
629        stream._varint(o.len());
630        stream._bytes(o.buf.as_slice());
631    }
632}
633
634#[inline(never)]
635pub fn emit_map<K, V, M: Map<K, V>>(
636    this: &M,
637    tag: u32,
638    ktag: u32,
639    vtag: u32,
640    stream: &mut OutputStream,
641    kmapper: fn(&mut OutputStream, u32, &K),
642    vmapper: fn(&mut OutputStream, u32, &V),
643) {
644    this.for_each(|(k, v)| {
645        stream._tag(tag);
646        assert_eq!(k as *const K as *const u8, stream.stack.top().0);
647        let len = stream.stack.pop().1;
648        stream._varint(len);
649        emit_raw(k, ktag, stream, kmapper);
650        emit_raw(v, vtag, stream, vmapper);
651    });
652}
653
654#[inline(never)]
655pub fn emit_oneof<'buf, T: BinProto<'buf>>(o: &Option<T>, stream: &mut OutputStream) {
656    if let Some(o) = o {
657        o.encode(stream)
658    }
659}
660
661pub fn _size_varint<T: Varint>(value: T) -> usize {
662    const VINT_LENS: [u8; 65] = [
663        10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4,
664        4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
665    ];
666    VINT_LENS[value.into_u64().leading_zeros() as usize] as _
667}
668
669pub fn size_varint<T: Varint>(value: &T, _: u32, _: &mut SizeStack) -> usize {
670    _size_varint(*value)
671}
672
673pub fn size_sigint<T: Sigint>(v: &T, _: u32, _: &mut SizeStack) -> usize {
674    _size_varint(v.encode().into_u64())
675}
676
677pub fn size_bytes<'x, T: BytesLike<'x>>(v: &T, _: u32, _: &mut SizeStack) -> usize {
678    _size_varint(v.len()) + v.len()
679}
680
681pub fn size_string<'x, T: BytesLike<'x>>(v: &T, _: u32, _: &mut SizeStack) -> usize {
682    _size_varint(v.len()) + v.len()
683}
684
685#[inline(always)]
686pub fn size_protoenum<T: Copy + Into<u32>>(v: &T, _: u32, _: &mut SizeStack) -> usize {
687    _size_varint(Into::<u32>::into(*v))
688}
689
690#[inline(always)]
691pub fn size_bool(_: &bool, _: u32, _: &mut SizeStack) -> usize {
692    1
693}
694
695#[inline(always)]
696pub fn size_fixed32<T>(_: &T, _: u32, _: &mut SizeStack) -> usize {
697    4
698}
699
700#[inline(always)]
701pub fn size_fixed64<T>(_: &T, _: u32, _: &mut SizeStack) -> usize {
702    8
703}
704
705pub fn size_nested<'a, T: BinProto<'a>>(v: &T, _: u32, stack: &mut SizeStack) -> usize {
706    let inner = stack.memo(v, |v, stack| v.size(stack));
707    _size_varint(inner) + inner
708}
709
710pub fn size_group<'a, T: BinProto<'a>>(v: &T, tag: u32, stack: &mut SizeStack) -> usize {
711    // We have endgrp tag to worry about
712    v.size(stack) + _size_varint(tag)
713}
714
715#[derive(Debug, Default)]
716pub struct SizeStack {
717    stack: Vec<(*const u8, usize)>,
718}
719
720impl SizeStack {
721    fn memo<T, F: FnOnce(&T, &mut Self) -> usize>(&mut self, p: &T, calc: F) -> usize {
722        let out = calc(p, self);
723        self.stack.push((p as *const T as *const u8, out));
724        out
725    }
726    fn top(&self) -> (*const u8, usize) {
727        *self.stack.last().unwrap()
728    }
729    fn pop(&mut self) -> (*const u8, usize) {
730        self.stack.pop().unwrap()
731    }
732}
733
734#[inline(always)]
735pub fn size_raw<T, F>(v: &T, tag: u32, stack: &mut SizeStack, sizer: F) -> usize
736where
737    F: Fn(&T, u32, &mut SizeStack) -> usize,
738{
739    _size_varint(tag) + sizer(v, tag, stack)
740}
741
742#[inline(never)]
743pub fn size_singular<T, F>(v: &T, tag: u32, stack: &mut SizeStack, sizer: F) -> usize
744where
745    T: PartialEq + Default,
746    F: Fn(&T, u32, &mut SizeStack) -> usize,
747{
748    if v != &Default::default() {
749        _size_varint(tag) + sizer(v, tag, stack)
750    } else {
751        0
752    }
753}
754
755#[inline(never)]
756pub fn size_optional<T, F>(v: &Option<T>, tag: u32, stack: &mut SizeStack, sizer: F) -> usize
757where
758    F: Fn(&T, u32, &mut SizeStack) -> usize,
759{
760    if let Some(v) = v {
761        _size_varint(tag) + sizer(v, tag, stack)
762    } else {
763        0
764    }
765}
766
767#[inline(never)]
768pub fn size_repeated<T, F>(v: &Vec<T>, tag: u32, stack: &mut SizeStack, sizer: F) -> usize
769where
770    F: Fn(&T, u32, &mut SizeStack) -> usize,
771{
772    v.iter().rev().map(|v| _size_varint(tag) + sizer(v, tag, stack)).sum()
773}
774
775#[inline(never)]
776pub fn size_packed<T, F>(v: &Vec<T>, tag: u32, stack: &mut SizeStack, sizer: F) -> usize
777where
778    F: Fn(&T, u32, &mut SizeStack) -> usize,
779{
780    if !v.is_empty() {
781        let len: usize = v.iter().rev().map(|v| sizer(v, tag, stack)).sum();
782        _size_varint(tag) + _size_varint(len) + len
783    } else {
784        0
785    }
786}
787
788#[inline(never)]
789pub fn size_oneof<'a, T: BinProto<'a>>(o: &Option<T>, stack: &mut SizeStack) -> usize {
790    if let Some(o) = o {
791        o.size(stack)
792    } else {
793        0
794    }
795}
796
797#[inline(never)]
798pub fn size_map<K, V, M: Map<K, V>>(
799    m: &M,
800    tag: u32,
801    ktag: u32,
802    vtag: u32,
803    stack: &mut SizeStack,
804    ksize: fn(&K, u32, &mut SizeStack) -> usize,
805    vsize: fn(&V, u32, &mut SizeStack) -> usize,
806) -> usize {
807    let mut sum = 0;
808    m.rev_for_each(|(k, v)| {
809        let elem = stack.memo(k, |_, stack| {
810            let v = vsize(v, vtag, stack);
811            let k = ksize(k, ktag, stack);
812            _size_varint(ktag) + _size_varint(vtag) + k + v
813        });
814        sum += _size_varint(tag) + _size_varint(elem) + elem
815    });
816    sum
817}
818
819pub fn decode<'buf, T: Default + BinProto<'buf>>(b: &'buf [u8]) -> Result<T> {
820    let mut out = T::default();
821    let mut is = InputStream::new(b);
822    while !is.is_empty() {
823        let tag = is._varint()?;
824        out.merge_field(tag, &mut is)?;
825    }
826    Ok(out)
827}
828
829pub fn encode<'buf, T: BinProto<'buf>>(b: &T) -> Result<Vec<u8>> {
830    let mut out = OutputStream::default();
831    b.size(&mut out.stack);
832    b.encode(&mut out);
833    Ok(out.buf)
834}
835
836pub fn encode_to<'buf, T: BinProto<'buf>>(b: &T, out: Vec<u8>) -> Result<Vec<u8>> {
837    let mut out = OutputStream::new(out);
838    b.size(&mut out.stack);
839    b.encode(&mut out);
840    Ok(out.buf)
841}