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>

source

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].

source§

impl<T, S: DerefMut<Target = [u8]>> Abomonated<T, S>

source

pub fn as_bytes(&self) -> &[u8]

Trait Implementations§

source§

impl<T, S: DerefMut<Target = [u8]>> Deref for Abomonated<T, S>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.

Auto Trait Implementations§

§

impl<T, S> Freeze for Abomonated<T, S>
where S: Freeze,

§

impl<T, S> RefUnwindSafe for Abomonated<T, S>

§

impl<T, S> Send for Abomonated<T, S>
where S: Send, T: Send,

§

impl<T, S> Sync for Abomonated<T, S>
where S: Sync, T: Sync,

§

impl<T, S> Unpin for Abomonated<T, S>
where S: Unpin, T: Unpin,

§

impl<T, S> UnwindSafe for Abomonated<T, S>
where S: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.