varing 0.13.0

Protobuf's varint encoding/decoding for LEB128 friendly types with full const context operations supports.
Documentation
use num_rational_0_4::Ratio;

use crate::{ConstDecodeError, ConstEncodeError, DecodeError, EncodeError, Varint};

use core::num::NonZeroUsize;

macro_rules! impl_varint_for_ratio {
  (@inner $($sign:ident::$bits:literal($merged_ty:ident)),+$(,)?) => {
    paste::paste! {
      $(
        impl Varint for Ratio<[< $sign $bits >]> {
          const MIN_ENCODED_LEN: NonZeroUsize = $merged_ty::MAX_ENCODED_LEN;

          const MAX_ENCODED_LEN: NonZeroUsize = $merged_ty::MAX_ENCODED_LEN;

          fn encoded_len(&self) -> NonZeroUsize {
            $crate::utils::[< pack_ $sign $bits >](*self.numer(), *self.denom()).encoded_len()
          }

          fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, EncodeError> {
            $crate::utils::[< pack_ $sign $bits >](*self.numer(), *self.denom()).encode(buf)
              .map_err(Into::into)
          }

          fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), DecodeError>
          where
            Self: Sized,
          {
            let (bytes_read, merged) = $merged_ty::decode(buf)?;
            let (numer, denom) = $crate::utils::[< unpack_ $sign $bits >](merged);
            if denom == 0 {
              return Err(DecodeError::other("denominator cannot be zero"));
            }
            Ok((bytes_read, Ratio::new_raw(numer, denom)))
          }
        }
      )*
    }
  };
  ($($bits:literal($merged_ty:ident)),+$(,)?) => {
    impl_varint_for_ratio!(@inner $(u::$bits($merged_ty)),+);
    impl_varint_for_ratio!(@inner $(i::$bits($merged_ty)),+);
  };
  (@const_inner $($sign:ident::$bits:literal($merged_ty:ident) {
    encoded_len_fn:$encoded_len_fn:path,
    encode_fn:$encode_fn:path,
    encode_to_fn:$encode_to_fn:path,
    decode_fn:$decode_fn:path,
  }),+$(,)?) => {
    paste::paste! {
      $(
        #[doc = "Returns the encoded length of the `Ratio<" $sign $bits ">` value."]
        #[inline]
        pub const fn [< encoded_ratio_ $sign $bits _len>](val: Ratio<[< $sign $bits >]>) -> NonZeroUsize {
          $encoded_len_fn($crate::utils::[< pack_ $sign $bits >](*val.numer(), *val.denom()))
        }

        #[doc = "Encodes the `Ratio<" $sign $bits ">` value."]
        #[inline]
        pub const fn [< encode_ratio_ $sign $bits >](val: Ratio<[< $sign $bits >]>) -> $crate::utils::Buffer<{ $merged_ty::MAX_ENCODED_LEN.get() + 1 }> {
          $encode_fn ($crate::utils::[< pack_ $sign $bits >](*val.numer(), *val.denom()))
        }

        #[doc = "Encodes the `Ratio<" $sign $bits ">` value into the provided buffer."]
        #[inline]
        pub const fn [< encode_ratio_ $sign $bits _to >](val: Ratio<[< $sign $bits >]>, buf: &mut [u8]) -> Result<NonZeroUsize, ConstEncodeError> {
          $encode_to_fn ($crate::utils::[< pack_ $sign $bits >](*val.numer(), *val.denom()), buf)
        }

        #[doc = "Decodes the `Ratio<" $sign $bits ">` value from the provided buffer."]
        #[inline]
        pub const fn [< decode_ratio_ $sign $bits >](buf: &[u8]) -> Result<(NonZeroUsize, Ratio<[< $sign $bits >]>), ConstDecodeError> {
          match $decode_fn(buf) {
            Ok((bytes_read, merged)) => {
              let (numer, denom) = $crate::utils::[< unpack_ $sign $bits >](merged);
              if denom == 0 {
                Err(ConstDecodeError::other("denominator cannot be zero"))
              } else {
                Ok((bytes_read, Ratio::new_raw(numer, denom)))
              }
            }
            Err(e) => Err(e),
          }
        }
      )*
    }
  };
  (@const $($bits:literal($merged_ty:ident)),+$(,)?) => {
    paste::paste! {
      impl_varint_for_ratio!(@const_inner $(u::$bits($merged_ty) {
        encoded_len_fn: $crate::[< encoded_ $merged_ty:snake _varint_len >],
        encode_fn: $crate::[< encode_ $merged_ty:snake _varint >],
        encode_to_fn: $crate::[< encode_ $merged_ty:snake _varint_to>],
        decode_fn: $crate::[< decode_ $merged_ty:snake _varint >],
      }),+);
      impl_varint_for_ratio!(@const_inner $(i::$bits($merged_ty) {
        encoded_len_fn: $crate::[< encoded_ $merged_ty:snake _varint_len >],
        encode_fn: $crate::[< encode_ $merged_ty:snake _varint >],
        encode_to_fn: $crate::[< encode_ $merged_ty:snake _varint_to>],
        decode_fn: $crate::[< decode_ $merged_ty:snake _varint >],
      }),+);
    }
  };
}

impl_varint_for_ratio!(8(u16), 16(u32), 32(u64), 64(u128));
impl_varint_for_ratio!(@const 8(u16), 16(u32), 32(u64), 64(u128));

#[cfg(feature = "ruint_1")]
mod ruint_1;

#[cfg(feature = "bnum_0_13")]
mod bnum_0_13;

#[cfg(feature = "bnum_0_13")]
#[cfg_attr(docsrs, doc(cfg(feature = "bnum_0_13")))]
pub use bnum_0_13::*;

#[cfg(test)]
mod tests;