Struct abomonation::abomonated::Abomonated
source · pub struct Abomonated<T, S: DerefMut<Target = [u8]>> { /* private fields */ }Expand description
A type wrapping owned decoded abomonated data.
This type ensures that decoding and pointer correction has already happened,
and implements Deref<Target=T> using a pointer cast (transmute).
#Safety
The safety of this type, and in particular its transute implementation of
the Deref trait, relies on the owned bytes not being externally mutated
once provided. You could imagine a new type implementing DerefMut as required,
but which also retains the ability (e.g. through RefCell) to mutate the bytes.
This would be very bad, but seems hard to prevent in the type system. Please
don’t do this.
You must also use a type S whose bytes have a fixed location in memory.
Otherwise moving an instance of Abomonated<T, S> may invalidate decoded
pointers, and everything goes badly.
#Examples
use std::ops::Deref;
use abomonation::{encode, decode};
use abomonation::abomonated::Abomonated;
// create some test data out of abomonation-approved types
let vector = (0..256u64).map(|i| (i, format!("{}", i)))
.collect::<Vec<_>>();
// encode a Vec<(u64, String)> into a Vec<u8>
let mut bytes = Vec::new();
unsafe { encode(&vector, &mut bytes); }
// attempt to decode `bytes` into a `&Vec<(u64, String)>`.
let maybe_decoded = unsafe { Abomonated::<Vec<(u64, String)>,_>::new(bytes) };
if let Some(decoded) = maybe_decoded {
// each `deref()` call is now just a pointer cast.
assert!(decoded.deref() == &vector);
}
else {
panic!("failed to decode");
}Implementations§
source§impl<T: Abomonation, S: DerefMut<Target = [u8]>> Abomonated<T, S>
impl<T: Abomonation, S: DerefMut<Target = [u8]>> Abomonated<T, S>
sourcepub unsafe fn new(bytes: S) -> Option<Self>
pub unsafe fn new(bytes: S) -> Option<Self>
Attempts to create decoded data from owned mutable bytes.
This method will return None if it is unable to decode the data with
type T.
#Examples
use std::ops::Deref;
use abomonation::{encode, decode};
use abomonation::abomonated::Abomonated;
// create some test data out of abomonation-approved types
let vector = (0..256u64).map(|i| (i, format!("{}", i)))
.collect::<Vec<_>>();
// encode a Vec<(u64, String)> into a Vec<u8>
let mut bytes = Vec::new();
unsafe { encode(&vector, &mut bytes); }
// attempt to decode `bytes` into a `&Vec<(u64, String)>`.
let maybe_decoded = unsafe { Abomonated::<Vec<(u64, String)>,_>::new(bytes) };
if let Some(decoded) = maybe_decoded {
// each `deref()` call is now just a pointer cast.
assert!(decoded.deref() == &vector);
}
else {
panic!("failed to decode");
}#Safety
The type S must have its bytes at a fixed location, which will
not change if the bytes: S instance is moved. Good examples are
Vec<u8> whereas bad examples are [u8; 16].