alchemy/src/transmutable.rs
Jason Travis Smith 03e9484e52 Fixed the conversion code to use macros I wrote.
The previous code was relying on the to_be and to_le functions from the
standard library. These now rely on macros that I wrote to handle the
bit packing and unpacking. These were macros and not functions because
it is really hard to define the types and capabilities needed to
turn them into general functions. As such, the macros should never be
published publically and the Converters should be used for conversions.

The Transmutable property should be used for serialization and internally
the primitive types, Elements, all use the Converter functions and any
other objects should use the Transmutable primitives to build their
binary forms.
2017-02-15 17:51:13 -05:00

1029 lines
25 KiB
Rust

#[cfg(feature="convert_sigils")]
use sigils::{Zero, Number, Real};
#[cfg(feature="convert_sigils")]
use sigils::vector::{Vector, Vector2, Vector3, Vector4};
#[cfg(feature="convert_sigils")]
use sigils::quaternion::Quaternion;
use ::byte_sized::{ByteSized, get_byte_size_of_string};
use ::converter::Converter;
use ::endian::{BigEndian, LittleEndian, PlatformEndian, NetworkEndian};
use ::endian::Endianess;
// From and Into are not used because we need to also
// know the endianess to use for converting.
/// A type that can be converted to and from bytes.
pub trait Transmutable
{
/// Transmute an array of bytes in the
/// platform's endian to this type.
fn from_bytes(buffer: &[u8]) -> Self;
/// Transmute an array of bytes in the
/// given endian to this type.
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self;
/// Transmute this type to an array of bytes in
/// the Platform's endian.
fn to_bytes(self) -> Vec<u8>;
/// Transmute this type to an array of bytes in
/// the desired endian.
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>;
/// Transmute this type to an array of bytes in
/// the Platform's endian.
fn as_bytes(&self) -> Vec<u8>;
/// Transmute this type to an array of bytes in
/// the desired endian.
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>;
/// Get the current size of this Transmutable in bytes.
fn determine_byte_size(&self) -> usize;
}
/// Handles the repetative endianess matching
/// for the primitive number types when converting
/// a number to bytes.
macro_rules! handle_endianess_to_bytes
{
($val: ident, $endianess: ident, $func: ident) =>
{
{
match $endianess
{
Endianess::Big =>
{
BigEndian::$func(*$val)
}
Endianess::Little =>
{
LittleEndian::$func(*$val)
}
Endianess::Platform =>
{
PlatformEndian::$func(*$val)
}
Endianess::Network =>
{
NetworkEndian::$func(*$val)
}
}
}
}
}
/// Handles the repetative endianess matching
/// for the primitive number types when converting
/// a number from bytes.
macro_rules! handle_endianess_from_bytes
{
($buffer: ident, $endianess: ident, $func: ident) =>
{
match $endianess
{
Endianess::Big =>
{
BigEndian::$func(&$buffer)
}
Endianess::Little =>
{
LittleEndian::$func(&$buffer)
}
Endianess::Platform =>
{
PlatformEndian::$func(&$buffer)
}
Endianess::Network =>
{
NetworkEndian::$func(&$buffer)
}
}
}
}
impl Transmutable for u8
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
#[allow(unused_variables)]
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= u8::BYTES);
// Just return the byte from the buffer.
// A single byte has no endian form.
buffer[0]
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
#[allow(unused_variables)]
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// A single byte has no endian form.
vec![*self]
}
fn determine_byte_size(&self) -> usize
{
u8::BYTES
}
}
impl Transmutable for u16
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= u16::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_u16)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Return the Endianess conversion.
handle_endianess_to_bytes!(self, endianess, u16_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
u16::BYTES
}
}
impl Transmutable for u32
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= u32::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_u32)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, u32_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
u32::BYTES
}
}
impl Transmutable for u64
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= u64::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_u64)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, u64_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
u64::BYTES
}
}
impl Transmutable for usize
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= usize::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_usize)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, usize_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
usize::BYTES
}
}
impl Transmutable for i8
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
#[allow(unused_variables)]
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= i8::BYTES);
buffer[0] as i8
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
#[allow(unused_variables)]
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
vec![*self as u8]
}
fn determine_byte_size(&self) -> usize
{
i8::BYTES
}
}
impl Transmutable for i16
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= i16::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_i16)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, i16_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
i16::BYTES
}
}
impl Transmutable for i32
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= i32::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_i32)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, i32_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
i32::BYTES
}
}
impl Transmutable for i64
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= i64::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_i64)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, i64_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
i64::BYTES
}
}
impl Transmutable for isize
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= isize::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_isize)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, isize_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
isize::BYTES
}
}
impl Transmutable for f32
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= f32::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_f32)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, f32_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
f32::BYTES
}
}
impl Transmutable for f64
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= f64::BYTES);
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_f64)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
handle_endianess_to_bytes!(self, endianess, f64_to_bytes)
}
fn determine_byte_size(&self) -> usize
{
f64::BYTES
}
}
impl Transmutable for String
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
// Convert the given bytes to this type and return it.
handle_endianess_from_bytes!(buffer, endianess, bytes_to_string)
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
// Convert this to bytes and add it to the buffer.
// We are not using the macro because *String is a str.
match endianess
{
Endianess::Big =>
{
BigEndian::string_to_bytes(self.clone())
}
Endianess::Little =>
{
LittleEndian::string_to_bytes(self.clone())
}
Endianess::Platform =>
{
PlatformEndian::string_to_bytes(self.clone())
}
Endianess::Network =>
{
NetworkEndian::string_to_bytes(self.clone())
}
}
}
fn determine_byte_size(&self) -> usize
{
get_byte_size_of_string(self)
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Vector2<T> where T: Number + ByteSized + Transmutable
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector2<T>;
// Determine the number of bytes requires to
// represent a Vector2.
vec = Vector2::<T>::zero();
byte_size = T::get_byte_size();
num_bytes = byte_size * vec.get_size() as usize;
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= num_bytes);
// Convert the given bytes to this type and return it.
vec.x = T::from_endian_bytes(&buffer[0..byte_size],
endianess);
vec.y = T::from_endian_bytes(&buffer[byte_size..num_bytes],
endianess);
vec
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// Determine the number of bytes requires to
// represent a Vector2.
byte_size = T::get_byte_size();
num_bytes = byte_size * self.get_size() as usize;
// Make sure that there is enough space to store
// the bytes from this type.
buffer = Vec::with_capacity(num_bytes);
// Convert this to bytes and add it to the buffer.
buffer.append(&mut self.x.as_endian_bytes(endianess));
buffer.append(&mut self.y.as_endian_bytes(endianess));
// Return the byte buffer.
buffer
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Vector3<T> where T: Number + ByteSized + Transmutable
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector3<T>;
// Determine the number of bytes requires to
// represent a Vector3.
vec = Vector3::<T>::zero();
byte_size = T::get_byte_size();
num_bytes = byte_size * vec.get_size() as usize;
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= num_bytes);
// Convert the given bytes to this type and return it.
vec.x = T::from_endian_bytes(&buffer[0..byte_size],
endianess);
vec.y = T::from_endian_bytes(&buffer[byte_size..(byte_size*2)],
endianess);
vec.z = T::from_endian_bytes(&buffer[(byte_size*2)..num_bytes],
endianess);
vec
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// Determine the number of bytes requires to
// represent a Vector3.
byte_size = T::get_byte_size();
num_bytes = byte_size * self.get_size() as usize;
// Make sure that there is enough space to store
// the bytes from this type.
buffer = Vec::with_capacity(num_bytes);
// Convert this to bytes and add it to the buffer.
buffer.append(&mut self.x.as_endian_bytes(endianess));
buffer.append(&mut self.y.as_endian_bytes(endianess));
buffer.append(&mut self.z.as_endian_bytes(endianess));
// Return the byte buffer.
buffer
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Vector4<T> where T: Number + ByteSized + Transmutable
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
let byte_size: usize;
let num_bytes: usize;
let mut vec: Vector4<T>;
// Determine the number of bytes requires to
// represent a Vector4.
vec = Vector4::<T>::zero();
byte_size = T::get_byte_size();
num_bytes = byte_size * vec.get_size() as usize;
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= num_bytes);
// Convert the given bytes to this type and return it.
vec.x = T::from_endian_bytes(&buffer[0..byte_size],
endianess);
vec.y = T::from_endian_bytes(&buffer[byte_size..(byte_size*2)],
endianess);
vec.z = T::from_endian_bytes(&buffer[(byte_size*2)..(byte_size*3)],
endianess);
vec.w = T::from_endian_bytes(&buffer[(byte_size*3)..num_bytes],
endianess);
vec
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// Determine the number of bytes requires to
// represent a Vector4.
byte_size = T::get_byte_size();
num_bytes = byte_size * self.get_size() as usize;
// Make sure that there is enough space to store
// the bytes from this type.
buffer = Vec::with_capacity(num_bytes);
// Convert this to bytes and add it to the buffer.
buffer.append(&mut self.x.as_endian_bytes(endianess));
buffer.append(&mut self.y.as_endian_bytes(endianess));
buffer.append(&mut self.z.as_endian_bytes(endianess));
buffer.append(&mut self.w.as_endian_bytes(endianess));
// Return the byte buffer.
buffer
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * self.get_size() as usize
}
}
#[cfg(feature="convert_sigils")]
impl<T> Transmutable for Quaternion<T>
where T: Real + ByteSized + Transmutable
{
fn from_bytes(buffer: &[u8]) -> Self
{
Self::from_endian_bytes(buffer, Endianess::Platform)
}
fn from_endian_bytes(buffer: &[u8], endianess: Endianess) -> Self
{
let byte_size: usize;
let num_bytes: usize;
let mut quat: Quaternion<T>;
// Determine the number of bytes requires to
// represent a Quaternion.
quat = Quaternion::<T>::zero();
byte_size = T::get_byte_size();
num_bytes = byte_size * 4usize;
// Make sure that there is enough data to read
// the bytes for this type.
assert!(buffer.len() >= num_bytes);
// Convert the given bytes to this type and return it.
quat.scalar = T::from_endian_bytes(&buffer[0..byte_size], endianess);
quat.vector =
Vector3::<T>::from_endian_bytes(&buffer[byte_size..num_bytes],
endianess);
quat
}
fn to_bytes(self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn to_endian_bytes(self, endianess: Endianess) -> Vec<u8>
{
self.as_endian_bytes(endianess)
}
fn as_bytes(&self) -> Vec<u8>
{
self.as_endian_bytes(Endianess::Platform)
}
fn as_endian_bytes(&self, endianess: Endianess) -> Vec<u8>
{
let byte_size: usize;
let num_bytes: usize;
let mut buffer: Vec<u8>;
// Determine the number of bytes requires to
// represent a Quaternion.
byte_size = T::get_byte_size();
num_bytes = byte_size * 4usize;
// Make sure that there is enough space to store
// the bytes from this type.
buffer = Vec::with_capacity(num_bytes);
// Convert this to bytes and add it to the buffer.
buffer.append(&mut self.scalar.as_endian_bytes(endianess));
buffer.append(&mut self.vector.as_endian_bytes(endianess));
// Return the byte buffer.
buffer
}
fn determine_byte_size(&self) -> usize
{
T::get_byte_size() * 4usize
}
}