Rust is confusing
ActivePublic

Authored by bcs on Mar 1 2018, 9:42 PM.
use num;
use std::mem::size_of;
#[derive(Debug)]
pub enum VarintError {
TooBigToEncode,
DecodeOverflow,
CantDecode,
}
pub type VarintResult<T> = Result<T, VarintError>;
fn needed_bytes<T>(x: T) -> VarintResult<usize>
where
T: num::PrimInt + num::Unsigned,
{
// let x1: u64 = num::cast(x).unwrap();
let size1: T = 1 << 6;
if x <= size1 {
return Ok(1);
} else if x <= 16383 {
return Ok(2);
} else if x <= 1073741823 {
return Ok(4);
} else if x <= 4611686018427387903 {
return Ok(8);
}
return Err(VarintError::TooBigToEncode);
}
const USIZE_BITS0: u32 = size_of::<usize>() as u32 * 8 - 1;
pub fn quic_encode<T>(x: T, o: &mut [u8]) -> VarintResult<usize>
where
T: num::PrimInt + num::Unsigned,
{
// use std::mem::size_of;
let x_be = x.to_be();
let bl = needed_bytes(x_be)?;
let bits: u8 = (USIZE_BITS0 - bl.leading_zeros()) as u8;
println!("bits: {:b}, bl: {}", bits, bl);
let raw_bytes = unsafe {
use std::mem;
mem::transmute::<T, [u8; 8]>(x.to_be())
};
for i in 0..bl {
o[i] |= raw_bytes[i];
}
o[0] &= 0b0011_1111;
o[0] |= bits << 6;
return Ok(bl);
}
pub fn quic_decode<T>(bx: &[u8]) -> VarintResult<T>
where
T: num::Num + num::NumCast + num::Unsigned,
{
if bx.len() < 1 {
return Err(VarintError::CantDecode);
}
use std::mem::size_of;
let bl = 1 << ((bx[0] & 0b1100_0000) >> 6);
println!("bl: {}", bl);
if bl > size_of::<T>() {
return Err(VarintError::DecodeOverflow);
}
let mut r: u64 = 0;
for i in 0..bl {
r |= bx[i] as u64;
r <<= 8;
}
r &= 0b0011_1111 << 8 * (bl - 1);
return Ok(num::cast(r).unwrap());
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug)]
struct TestCase<'a> {
bytes: &'a [u8],
repr: u64,
}
static TEST_CASES: &[TestCase] = &[
TestCase {
bytes: &[0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c],
repr: 151288809941952652,
},
TestCase {
bytes: &[0x9d, 0x7f, 0x3e, 0x7d],
repr: 494878333,
},
TestCase {
bytes: &[0x7b, 0xbd],
repr: 15293,
},
TestCase {
bytes: &[0x40, 0x25],
repr: 37,
},
TestCase {
bytes: &[0x25],
repr: 37,
},
];
#[test]
#[ignore]
fn test_decode() {
for case in TEST_CASES {
println!("test case: {:?}", case);
let mut out: [u8; 8] = [0; 8];
let res = quic_decode::<u64>(case.bytes);
assert_eq!(res.is_ok(), true);
let ures = res.unwrap();
let _eres = quic_encode(ures, &mut out);
println!("eres: {:?}", out);
assert_eq!(ures, case.repr);
}
}
#[test]
fn test_encode() {
for case in TEST_CASES {
println!("test case: {:?}", case);
let mut out: [u8; 8] = [0; 8];
let res = quic_encode(case.repr, &mut out[0..case.bytes.len()]);
assert_eq!(res.is_ok(), true);
let num_bytes = res.unwrap();
assert_eq!(num_bytes, case.bytes.len());
assert_eq!(&out[0..num_bytes], case.bytes);
}
}
}
bcs created this paste.Mar 1 2018, 9:42 PM

Compile failures:

   Compiling rquic v0.1.0 (file:///home/bcs/Projects/rquic)
error[E0308]: mismatched types
  --> src/varint.rs:18:20
   |
18 |     let size1: T = 1 << 6;
   |                    ^^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:18:20
   |
18 |     let size1: T = 1 << 6;
   |                    ^^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:21:20
   |
21 |     } else if x <= 16383 {
   |                    ^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:21:20
   |
21 |     } else if x <= 16383 {
   |                    ^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:23:20
   |
23 |     } else if x <= 1073741823 {
   |                    ^^^^^^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:23:20
   |
23 |     } else if x <= 1073741823 {
   |                    ^^^^^^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:25:20
   |
25 |     } else if x <= 4611686018427387903 {
   |                    ^^^^^^^^^^^^^^^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error[E0308]: mismatched types
  --> src/varint.rs:25:20
   |
25 |     } else if x <= 4611686018427387903 {
   |                    ^^^^^^^^^^^^^^^^^^^ expected type parameter, found integral variable
   |
   = note: expected type `T`
              found type `{integer}`

error: aborting due to 4 previous errors

If you want more information on this error, try using "rustc --explain E0308"
error: aborting due to 4 previous errors

If you want more information on this error, try using "rustc --explain E0308"
error: Could not compile `rquic`.
warning: build failed, waiting for other jobs to finish...
error: Could not compile `rquic`.

To learn more, run the command again with --verbose.