[][src]Struct abomonation::abomonated::Abomonated

pub struct Abomonated<T, S: DerefMut<Target = [u8]>> { /* fields omitted */ }

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");
}

Methods

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

pub unsafe fn new(bytes: S) -> Option<Self>[src]

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

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

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

Trait Implementations

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

type Target = T

The resulting type after dereferencing.

Auto Trait Implementations

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> Send for Abomonated<T, S> where
    S: Send,
    T: Send

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

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

Blanket Implementations

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]