use super::traits::{EncodeNumber, EncodeNumberInclusive};
impl EncodeNumber for u8 {
fn encode_number(&self) -> Vec<u8> {
vec![b'3', *self]
}
}
impl EncodeNumber for u16 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'4'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for u32 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'5'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for u64 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'6'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for u128 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'7'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for usize {
fn encode_number(&self) -> Vec<u8> {
if *self <= u8::MAX as usize {
vec![b'3', *self as u8]
} else if *self <= u16::MAX as usize {
let mut result = vec![b'4'];
result.extend_from_slice(&(*self as u16).to_be_bytes());
result
} else if *self <= u32::MAX as usize {
let mut result = vec![b'5'];
result.extend_from_slice(&(*self as u32).to_be_bytes());
result
} else if *self <= u64::MAX as usize {
let mut result = vec![b'6'];
result.extend_from_slice(&(*self as u64).to_be_bytes());
result
} else {
let mut result = vec![b'7'];
result.extend_from_slice(&(*self as u128).to_be_bytes());
result
}
}
}
impl EncodeNumberInclusive for usize {
fn encode_usize_inclusive(&self) -> Vec<u8> {
let base = 8; let mut size = 8; let mut result = vec![b'u'];
let mut adder = base + size; let mut cutoff = 0x80 - adder + 0x80;
if *self < cutoff {
result.push(b'3');
result.push((*self + adder) as u8);
return result;
}
size *= 2;
adder = base + size; cutoff = u16::MAX as usize - adder; if *self <= cutoff {
result.push(b'4');
result.extend_from_slice(&((*self + adder) as u16).to_be_bytes());
return result;
}
size *= 2;
adder = base + size; cutoff = u32::MAX as usize - adder; if *self <= cutoff {
result.push(b'5');
result.extend_from_slice(&((*self + adder) as u32).to_be_bytes());
return result;
}
size *= 2;
adder = base + size; cutoff = u64::MAX as usize - adder; if *self <= cutoff {
result.push(b'6');
result.extend_from_slice(&((*self + adder) as u64).to_be_bytes());
return result;
}
size *= 2;
adder = base + size; cutoff = u128::MAX as usize - adder; if *self <= cutoff {
result.push(b'7');
result.extend_from_slice(&((*self + adder) as u128).to_be_bytes());
return result;
}
size *= 2;
adder = base + size;
cutoff = u128::MAX as usize - adder;
if *self <= cutoff {
result.push(b'8');
result.extend_from_slice(&((*self + adder) as u128).to_be_bytes());
return result;
}
panic!("Value too large for inclusive encoding (u8 not implemented)");
}
}
impl EncodeNumber for i8 {
fn encode_number(&self) -> Vec<u8> {
vec![b'3', *self as u8]
}
}
impl EncodeNumber for i16 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'4'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for i32 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'5'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for i64 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'6'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for i128 {
fn encode_number(&self) -> Vec<u8> {
let mut result = vec![b'7'];
result.extend_from_slice(&self.to_be_bytes());
result
}
}
impl EncodeNumber for isize {
fn encode_number(&self) -> Vec<u8> {
if *self >= 0 {
if *self <= u8::MAX as isize {
vec![b'3', *self as u8]
} else if *self <= u16::MAX as isize {
let mut result = vec![b'4'];
result.extend_from_slice(&(*self as i16).to_be_bytes());
result
} else if *self <= u32::MAX as isize {
let mut result = vec![b'5'];
result.extend_from_slice(&(*self as i32).to_be_bytes());
result
} else if *self <= u64::MAX as isize {
let mut result = vec![b'6'];
result.extend_from_slice(&(*self as i64).to_be_bytes());
result
} else {
let mut result = vec![b'7'];
result.extend_from_slice(&(*self as i128).to_be_bytes());
result
}
} else if *self >= i8::MIN as isize {
vec![b'3', *self as u8]
} else if *self >= i16::MIN as isize {
let mut result = vec![b'4'];
result.extend_from_slice(&(*self as i16).to_be_bytes());
result
} else if *self >= i32::MIN as isize {
let mut result = vec![b'5'];
result.extend_from_slice(&(*self as i32).to_be_bytes());
result
} else if *self >= i64::MIN as isize {
let mut result = vec![b'6'];
result.extend_from_slice(&(*self as i64).to_be_bytes());
result
} else {
let mut result = vec![b'7'];
result.extend_from_slice(&(*self as i128).to_be_bytes());
result
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_encode_u8() {
assert_eq!(42u8.encode_number(), vec![b'3', 42]);
assert_eq!(255u8.encode_number(), vec![b'3', 255]);
}
#[test]
fn test_encode_u16() {
assert_eq!(300u16.encode_number(), vec![b'4', 0x01, 0x2C]);
assert_eq!(4096u16.encode_number(), vec![b'4', 0x10, 0x00]);
}
#[test]
fn test_encode_usize_auto() {
assert_eq!(42usize.encode_number(), vec![b'3', 42]);
assert_eq!(300usize.encode_number(), vec![b'4', 0x01, 0x2C]);
assert_eq!(
100000usize.encode_number(),
vec![b'5', 0x00, 0x01, 0x86, 0xA0]
);
}
#[test]
fn test_encode_inclusive() {
let result = 256usize.encode_usize_inclusive();
assert_eq!(result[0], b'u');
assert_eq!(result[1], b'4');
assert_eq!(result[2], 0x01);
assert_eq!(result[3], 0x18);
}
#[test]
fn test_encode_isize_positive() {
assert_eq!(42isize.encode_number(), vec![b'3', 42]);
}
#[test]
fn test_encode_isize_negative() {
assert_eq!((-42isize).encode_number(), vec![b'3', 0xD6]); }
}