micropb 0.6.0

Rust Protobuf library targetting embedded systems and no_std environments
Documentation
#[cfg(feature = "decode")]
use crate::decode::{DecodeError, PbDecoder, PbRead};
#[cfg(feature = "encode")]
use crate::encode::{PbEncoder, PbWrite};

#[cfg(feature = "decode")]
/// Protobuf message that can be decoded from the wire.
///
/// Implementations are auto-generated by `micropb-gen`.
pub trait MessageDecode {
    /// Decode an instance of the message from the decoder and merge it into `self`.
    ///
    /// Length of the message needs to be known beforehand.
    fn decode<R: PbRead>(
        &mut self,
        decoder: &mut PbDecoder<R>,
        len: usize,
    ) -> Result<(), DecodeError<R::Error>>;

    /// Decode an instance of the message from the provided bytes
    fn decode_from_bytes(
        &mut self,
        bytes: &[u8],
    ) -> Result<(), DecodeError<core::convert::Infallible>> {
        let mut decoder = PbDecoder::new(bytes);
        self.decode(&mut decoder, bytes.len())
    }

    /// Decode an instance of the message from the decoder as a length-delimited record, starting with a length
    /// prefix.
    fn decode_len_delimited<R: PbRead>(
        &mut self,
        decoder: &mut PbDecoder<R>,
    ) -> Result<(), DecodeError<R::Error>> {
        decoder.decode_len_record(|len, _, decoder| self.decode(decoder, len))
    }
}

#[cfg(feature = "decode")]
impl<T: MessageDecode> MessageDecode for &mut T {
    fn decode<R: PbRead>(
        &mut self,
        decoder: &mut PbDecoder<R>,
        len: usize,
    ) -> Result<(), DecodeError<R::Error>> {
        (*self).decode(decoder, len)
    }

    fn decode_from_bytes(
        &mut self,
        bytes: &[u8],
    ) -> Result<(), DecodeError<core::convert::Infallible>> {
        (*self).decode_from_bytes(bytes)
    }

    fn decode_len_delimited<R: PbRead>(
        &mut self,
        decoder: &mut PbDecoder<R>,
    ) -> Result<(), DecodeError<R::Error>> {
        (*self).decode_len_delimited(decoder)
    }
}

#[cfg(feature = "encode")]
/// Protobuf message that can be encoded onto the wire.
///
/// Implementations are auto-generated by `micropb-gen`.
pub trait MessageEncode {
    /// Maximum encoded size of the message on the wire.
    ///
    /// If `MAX_SIZE` is `Err`, that means the message size is unbounded, due to having custom
    /// fields or collections fields without a fixed capacity, such as `Vec`. The generator will
    /// populate the `Err` with a message indicating the reason.
    ///
    /// The recommended way to use `MAX_SIZE` in const context is via
    /// [`max_encoded_size`](crate::size::max_encoded_size).
    const MAX_SIZE: Result<usize, &'static str>;

    /// Encode this message using the encoder.
    fn encode<W: PbWrite>(&self, encoder: &mut PbEncoder<W>) -> Result<(), W::Error>;

    /// Encode this message as a length-delimited record, starting with a length prefix.
    fn encode_len_delimited<W: PbWrite>(&self, encoder: &mut PbEncoder<W>) -> Result<(), W::Error> {
        encoder.encode_varint32(self.compute_size() as u32)?;
        self.encode(encoder)
    }

    /// Compute the size of this message on the wire.
    fn compute_size(&self) -> usize;
}

#[doc(hidden)]
#[cfg(feature = "encode")]
pub trait MessageEncodeCached {
    const MAX_SIZE: Result<usize, &'static str>;

    type Cache: Default;

    fn populate_cache(&self) -> Self::Cache;

    fn encode_cached<W: PbWrite>(
        &self,
        encoder: &mut PbEncoder<W>,
        cache: &Self::Cache,
    ) -> Result<(), W::Error>;

    fn compute_size_cached(&self, cache: &Self::Cache) -> usize;

    fn encode_len_delimited_cached<W: PbWrite>(
        &self,
        encoder: &mut PbEncoder<W>,
        cache: &Self::Cache,
    ) -> Result<(), W::Error> {
        encoder.encode_varint32(self.compute_size_cached(cache) as u32)?;
        self.encode_cached(encoder, cache)
    }
}

#[cfg(feature = "encode")]
impl<T: MessageEncodeCached> MessageEncode for T {
    const MAX_SIZE: Result<usize, &'static str> = T::MAX_SIZE;

    fn encode<W: PbWrite>(&self, encoder: &mut PbEncoder<W>) -> Result<(), W::Error> {
        let cache = self.populate_cache();
        self.encode_cached(encoder, &cache)
    }

    fn compute_size(&self) -> usize {
        let cache = self.populate_cache();
        self.compute_size_cached(&cache)
    }

    fn encode_len_delimited<W: PbWrite>(&self, encoder: &mut PbEncoder<W>) -> Result<(), W::Error> {
        let cache = self.populate_cache();
        self.encode_len_delimited_cached(encoder, &cache)
    }
}