pub trait CreateFrom {
fn create(v: [u32; 4]) -> Self;
}
impl CreateFrom for char {
fn create(v: [u32; 4]) -> char {
let mut result = v[0] % (0xD7FF + (0xE000..=0x10FFFF).count() as u32);
if result > 0xD7FF {
result += 0xE000
}
char::from_u32(result).expect("Oops")
}
}
impl CreateFrom for bool {
fn create(v: [u32; 4]) -> bool {
(v[0] & 1) != 0
}
}
impl CreateFrom for u8 {
fn create(v: [u32; 4]) -> u8 {
(v[0] & 0xFF) as u8
}
}
impl CreateFrom for i8 {
fn create(v: [u32; 4]) -> i8 {
(v[0] & 0xFF) as i8
}
}
impl CreateFrom for u16 {
fn create(v: [u32; 4]) -> u16 {
(v[0] & 0xFFFF) as u16
}
}
impl CreateFrom for i16 {
fn create(v: [u32; 4]) -> i16 {
(v[0] & 0xFFFF) as i16
}
}
impl CreateFrom for u32 {
fn create(v: [u32; 4]) -> u32 {
v[0]
}
}
impl CreateFrom for i32 {
fn create(v: [u32; 4]) -> i32 {
v[0] as i32
}
}
impl CreateFrom for u64 {
fn create(v: [u32; 4]) -> u64 {
((v[0] as u64) << 32) | (v[1] as u64)
}
}
impl CreateFrom for i64 {
fn create(v: [u32; 4]) -> i64 {
((v[0] as i64) << 32) | (v[1] as i64)
}
}
impl CreateFrom for u128 {
fn create(v: [u32; 4]) -> u128 {
let mut i = (v[0] as u128) << 96;
i |= (v[1] as u128) << 64;
i |= (v[2] as u128) << 32;
i |= v[3] as u128;
i
}
}
impl CreateFrom for i128 {
fn create(v: [u32; 4]) -> i128 {
let mut i = (v[0] as i128) << 96;
i |= (v[1] as i128) << 64;
i |= (v[2] as i128) << 32;
i |= v[3] as i128;
i
}
}
impl CreateFrom for usize {
fn create(v: [u32; 4]) -> usize {
let mut i = (v[0] as u128) << 96;
i |= (v[1] as u128) << 64;
i |= (v[2] as u128) << 32;
i |= v[3] as u128;
i as usize
}
}
impl CreateFrom for isize {
fn create(v: [u32; 4]) -> isize {
let mut i = (v[0] as u128) << 96;
i |= (v[1] as u128) << 64;
i |= (v[2] as u128) << 32;
i |= v[3] as u128;
i as isize
}
}
impl CreateFrom for f32 {
fn create(v: [u32; 4]) -> f32 {
let mut i = v[0];
let mask = 0b0_11111111_00000000000000000000000;
if (i & mask) >> 23 == 0xFF {
i ^= (v[1] & 0xFF) << 23
}
f32::from_bits(i)
}
}
impl CreateFrom for f64 {
fn create(v: [u32; 4]) -> f64 {
let mut i = ((v[0] as u64) << 32) | (v[1] as u64);
let mask: u64 = 0b0_11111111111_00000000000000000000000000000000000000000000000000000;
if (i & mask) >> 52 == 0x07FF {
i ^= ((v[2] & 0x07FF) as u64) << 52;
}
f64::from_bits(i)
}
}