1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::{mem,slice};

///A type which is representable as bytes
pub trait As{
	///Represent a pointer to a type as an array of bytes
	fn as_bytes(&self) -> &[u8];

	///Represent a mutable pointer to a type as a mutable array of bytes
	unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
}

///A type which can be constructed from bytes unsafely
pub trait From{
	///Construct a type from an array of bytes
	unsafe fn from_bytes(bytes: &[u8]) -> Self;
}

impl<T> As for T
	where T: Sized + Copy
{
	#[inline(always)]
	fn as_bytes(&self) -> &[u8]{
		unsafe{slice::from_raw_parts(
			self as *const T as *const u8,
			mem::size_of::<T>()
		)}
	}

	#[inline(always)]
	unsafe fn as_bytes_mut(&mut self) -> &mut [u8]{
		slice::from_raw_parts_mut(
			self as *mut T as *mut u8,
			mem::size_of::<T>()
		)
	}
}

//TODO: This is safe if all values are valid, but not otherwise (What is this called? Total relation/mapping for bytes?)
impl<T> From for T
	where T: Sized + Copy
{
	#[inline(always)]
	unsafe fn from_bytes(bytes: &[u8]) -> Self{
		debug_assert!(bytes.len() >= mem::size_of::<T>());
		*(bytes.as_ptr() as *const T)
	}
}

#[test]
fn test(){
	let list: [u8;4] = [0x00,0x01,0x02,0x03];
	assert_eq!((list[0],list[1],list[2],list[3]),(0x00,0x01,0x02,0x03));

	let bytes = list.as_bytes();
	assert_eq!((bytes[0],bytes[1],bytes[2],bytes[3]),(0x00,0x01,0x02,0x03));

	let list: [u8;4] = unsafe{From::from_bytes(bytes)};
	assert_eq!((list[0],list[1],list[2],list[3]),(0x00,0x01,0x02,0x03));
}