use crate::{DecodeError, EncodeError, Varint, ruint_impl::Packable};
use ::ruint_1::Uint;
use num_rational_0_4::Ratio;
use core::num::NonZeroUsize;
#[cfg(not(feature = "bnum_0_13"))]
use ::ruint_1::aliases::U256;
#[cfg(not(feature = "bnum_0_13"))]
impl_varint_for_ratio!(128(U256));
macro_rules! impl_varint_for_ratio_ruint {
($($bits:literal),+$(,)?) => {
paste::paste! {
$(
impl Varint for Ratio<Uint<$bits, { $bits / 64 } >> {
const MIN_ENCODED_LEN: NonZeroUsize = Uint::<{$bits * 2}, {($bits * 2) / 64}>::MAX_ENCODED_LEN;
const MAX_ENCODED_LEN: NonZeroUsize = Uint::<{$bits * 2}, {($bits * 2) / 64}>::MAX_ENCODED_LEN;
fn encoded_len(&self) -> NonZeroUsize {
Packable::<Uint::<{$bits * 2}, {($bits * 2) / 64}>>::pack(*self.numer(), *self.denom()).encoded_len()
}
fn encode(&self, buf: &mut [u8]) -> Result<NonZeroUsize, EncodeError> {
Packable::<Uint::<{$bits * 2}, {($bits * 2) / 64}>>::pack(*self.numer(), *self.denom()).encode(buf)
}
fn decode(buf: &[u8]) -> Result<(NonZeroUsize, Self), DecodeError>
where
Self: Sized,
{
let (bytes_read, merged) = Uint::< { $bits * 2 }, {($bits * 2) / 64}>::decode(buf)?;
let (numer, denom): (Uint<$bits, { $bits / 64 } >, Uint<$bits, { $bits / 64 } >) = Packable::<Uint::<{$bits * 2}, {($bits * 2) / 64}>>::unpack(merged);
if denom.is_zero() {
return Err(DecodeError::other("denominator cannot be zero"));
}
Ok((bytes_read, Ratio::new_raw(numer, denom)))
}
}
)*
}
};
}
impl_varint_for_ratio_ruint!(64, 128, 192, 256, 320, 384, 448, 512, 768, 1024, 2048, 4096,);