Skip to content

Commit

Permalink
Impl TlWrite and TlRead for NonZero*
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Sep 19, 2024
1 parent 3b12e2c commit be26142
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "tl-proto"
description = "A collection of traits for working with TL serialization/deserialization"
authors = ["Ivan Kalinin <[email protected]>"]
repository = "https://github.com/broxus/tl-proto"
version = "0.4.7"
version = "0.4.8"
edition = "2021"
include = ["src/**/*.rs", "README.md"]
license = "MIT"
Expand Down
136 changes: 136 additions & 0 deletions src/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,139 @@ fn convert_f64(f: &f64) -> u64 {

const BOOL_FALSE: u32 = 0xbc799737;
const BOOL_TRUE: u32 = 0x997275b5;

macro_rules! impl_non_zero {
($($ty:ty => ($write_method:ident, $read_ty:ty)),*$(,)?) => {
$(
impl TlWrite for $ty {
type Repr = Bare;

#[inline(always)]
fn max_size_hint(&self) -> usize {
std::mem::size_of::<Self>()
}

#[inline(always)]
fn write_to<T>(&self, packet: &mut T)
where
T: TlPacket,
{
packet.$write_method(self.get())
}
}

impl TlRead<'_> for $ty {
type Repr = Bare;

#[inline(always)]
fn read_from(packet: &[u8], offset: &mut usize) -> TlResult<Self> {
match <$ty>::new(<$read_ty>::read_from(packet, offset)?) {
Some(value) => Ok(value),
None => Err(TlError::InvalidData),
}
}
}

)*
};
}

impl_non_zero! {
std::num::NonZeroU32 => (write_u32, u32),
std::num::NonZeroI32 => (write_i32, i32),
std::num::NonZeroU64 => (write_u64, u64),
std::num::NonZeroI64 => (write_i64, i64),
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn write_non_zero() {
macro_rules! decl_writes {
($($ty:ty => [$($lit:expr),*$(,)?]),*$(,)?) => {
$($(assert_eq!(crate::serialize(<$ty>::new($lit).unwrap()), $lit.to_le_bytes());)*)*
};
}

decl_writes! {
std::num::NonZeroU32 => [1u32, 123u32, u32::MAX],
std::num::NonZeroI32 => [-123i32, 123i32, i32::MIN, i32::MAX],
std::num::NonZeroU64 => [1u64, 123u64, u64::MAX],
std::num::NonZeroI64 => [-123i64, 123i64, i64::MIN, i64::MAX]
}
}

#[test]
fn read_non_zero() {
// u32
assert!(matches!(
std::num::NonZeroU32::read_from(&[0, 0], &mut 0).unwrap_err(),
TlError::UnexpectedEof
));
assert!(matches!(
std::num::NonZeroU32::read_from(&[0, 0, 0, 0], &mut 0).unwrap_err(),
TlError::InvalidData
));
let mut offset = 0;
assert_eq!(
std::num::NonZeroU32::read_from(&[123, 0, 0, 0], &mut offset).unwrap(),
std::num::NonZeroU32::new(123).unwrap(),
);
assert_eq!(offset, 4);

// i32
assert!(matches!(
std::num::NonZeroI32::read_from(&[0, 0], &mut 0).unwrap_err(),
TlError::UnexpectedEof
));
assert!(matches!(
std::num::NonZeroI32::read_from(&[0, 0, 0, 0], &mut 0).unwrap_err(),
TlError::InvalidData
));
let mut offset = 0;
assert_eq!(
std::num::NonZeroI32::read_from(&[0xfe, 0xff, 0xff, 0xff], &mut offset).unwrap(),
std::num::NonZeroI32::new(-2).unwrap(),
);
assert_eq!(offset, 4);

// u64
assert!(matches!(
std::num::NonZeroU64::read_from(&[0, 0, 0, 0], &mut 0).unwrap_err(),
TlError::UnexpectedEof
));
assert!(matches!(
std::num::NonZeroU64::read_from(&[0, 0, 0, 0, 0, 0, 0, 0], &mut 0).unwrap_err(),
TlError::InvalidData
));
let mut offset = 0;
assert_eq!(
std::num::NonZeroU64::read_from(&[123, 0, 0, 0, 0, 0, 0, 0], &mut offset).unwrap(),
std::num::NonZeroU64::new(123).unwrap(),
);
assert_eq!(offset, 8);

// i64
assert!(matches!(
std::num::NonZeroI64::read_from(&[0, 0, 0, 0], &mut 0).unwrap_err(),
TlError::UnexpectedEof
));

assert!(matches!(
std::num::NonZeroI64::read_from(&[0, 0, 0, 0, 0, 0, 0, 0], &mut 0).unwrap_err(),
TlError::InvalidData
));
let mut offset = 0;
assert_eq!(
std::num::NonZeroI64::read_from(
&[0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
&mut offset
)
.unwrap(),
std::num::NonZeroI64::new(-2).unwrap(),
);
assert_eq!(offset, 8);
}
}

0 comments on commit be26142

Please sign in to comment.