From 0b541716ed665d9cbbe2ae2515b3542ed15a87aa Mon Sep 17 00:00:00 2001 From: Alexander Koptelov Date: Tue, 3 Oct 2023 19:59:37 +0300 Subject: [PATCH] Consistent unsigned representation Fix: #43 Fix: #38 --- src/number.rs | 141 ++++++++++++++++++++++---------------------- src/v2/generated.rs | 4 +- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/src/number.rs b/src/number.rs index 023a37a..7b83842 100644 --- a/src/number.rs +++ b/src/number.rs @@ -9,9 +9,8 @@ pub struct Number(pub T); impl std::fmt::Debug for Number { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let Self(inner) = self; // Avoid vertical alignment - f.write_fmt(format_args!("Number({:?})", inner)) + f.write_fmt(format_args!("Number({inner:?})", inner = self.0)) } } @@ -139,85 +138,85 @@ where } } -impl binprot::BinProtRead for Number -where - T: binprot::BinProtRead, -{ - fn binprot_read(r: &mut R) -> Result - where - Self: Sized, - { - T::binprot_read(r).map(Self) - } -} +macro_rules! binprot_number { + ($base_type:ident, $binprot_type:ident) => { + impl binprot::BinProtRead for Number<$base_type> { + fn binprot_read(r: &mut R) -> Result + where + Self: Sized, + { + $binprot_type::binprot_read(r).map(|v| Self(v as $base_type)) + } + } -impl binprot::BinProtWrite for Number -where - T: binprot::BinProtWrite, -{ - fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { - self.0.binprot_write(w) - } + impl binprot::BinProtWrite for Number<$base_type> { + fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { + (self.0 as $binprot_type).binprot_write(w) + } + } + }; } +binprot_number!(i32, i32); +binprot_number!(i64, i64); +binprot_number!(u32, i32); +binprot_number!(u64, i64); +binprot_number!(f64, f64); + #[cfg(test)] mod tests { use binprot::{BinProtRead, BinProtWrite}; - #[test] - fn u32_roundtrip() { - for u32 in [ - 0, - 1, - u8::MAX as u32, - u16::MAX as u32, - u32::MAX, - i8::MAX as u32, - i16::MAX as u32, - i32::MAX as u32, - ] { - let mut buf = Vec::new(); - u32.binprot_write(&mut buf).unwrap(); - let mut r = buf.as_slice(); - if u32 <= 0x7f { - assert_eq!(r[0], u32 as u8); - } else { - assert!(matches!(r[0], 0xfe | 0xfd | 0xfc)); + macro_rules! number_test { + ($name:ident, $ty:ident) => { + #[test] + fn $name() { + for n in [ + 0, + 1, + u8::MAX as $ty, + u16::MAX as $ty, + u32::MAX as $ty, + u64::MAX as $ty, + i8::MAX as $ty, + i16::MAX as $ty, + i32::MAX as $ty, + i64::MAX as $ty, + ] { + let n: super::Number<$ty> = n.into(); + let mut buf = Vec::new(); + n.binprot_write(&mut buf).unwrap(); + let mut r = buf.as_slice(); + let n_ = super::Number::<$ty>::binprot_read(&mut r).unwrap(); + assert_eq!(r.len(), 0); + assert_eq!(n, n_); + } } - let u32_ = u32::binprot_read(&mut r).unwrap(); - assert_eq!(r.len(), 0); - assert_eq!(u32, u32_); - } + }; } - #[test] - fn i32_roundtrip() { - for i32 in [ - 0, - 1, - u8::MAX as i32, - u16::MAX as i32, - u32::MAX as i32, - i8::MAX as i32, - i16::MAX as i32, - i32::MAX as i32, - i8::MIN as i32, - i16::MIN as i32, - i32::MIN as i32, - ] { - let mut buf = Vec::new(); - i32.binprot_write(&mut buf).unwrap(); - let mut r = buf.as_slice(); - if -0x80 <= i32 && i32 < 0 { - assert_eq!(r[0], 0xff); - } else if 0 <= i32 && i32 <= 0x80 { - assert_eq!(r[0], i32 as u8); - } else { - assert!(matches!(r[0], 0xfe | 0xfd | 0xfc)); + macro_rules! max_number_test { + ($name:ident, $ty:ident) => { + #[test] + fn $name() { + let binprot = b"\xff\xff"; + let mut r = &binprot[..]; + let n = super::Number::<$ty>::binprot_read(&mut r).unwrap(); + assert_eq!(n.0, $ty::MAX); + + let n: super::Number<$ty> = $ty::MAX.into(); + let mut buf = Vec::new(); + n.binprot_write(&mut buf).unwrap(); + assert_eq!(buf.as_slice(), b"\xff\xff"); } - let i32_ = i32::binprot_read(&mut r).unwrap(); - assert_eq!(r.len(), 0); - assert_eq!(i32, i32_); - } + }; } + + number_test!(i32_roundtrip, i32); + number_test!(u32_roundtrip, u32); + number_test!(i64_roundtrip, i64); + number_test!(u64_roundtrip, u64); + + max_number_test!(u32_max, u32); + max_number_test!(u64_max, u64); } diff --git a/src/v2/generated.rs b/src/v2/generated.rs index f609ed9..33b0860 100644 --- a/src/v2/generated.rs +++ b/src/v2/generated.rs @@ -792,7 +792,7 @@ pub struct NonZeroCurvePointUncompressedStableV1 { /// Gid: `125` /// Location: [src/int64.ml:6:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int64.ml#L6) #[derive(Clone, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct UnsignedExtendedUInt64Int64ForVersionTagsStableV1(pub crate::number::Int64); +pub struct UnsignedExtendedUInt64Int64ForVersionTagsStableV1(pub crate::number::UInt64); /// **OCaml name**: `Unsigned_extended.UInt32.Stable.V1` /// @@ -803,7 +803,7 @@ pub struct UnsignedExtendedUInt64Int64ForVersionTagsStableV1(pub crate::number:: /// Gid: `119` /// Location: [src/int32.ml:6:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int32.ml#L6) #[derive(Clone, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref, Default)] -pub struct UnsignedExtendedUInt32StableV1(pub crate::number::Int32); +pub struct UnsignedExtendedUInt32StableV1(pub crate::number::UInt32); /// **OCaml name**: `Mina_numbers__Nat.Make32.Stable.V1` ///