[][src]Trait rustbus::wire::unmarshal::traits::Unmarshal

pub trait Unmarshal<'r, 'buf: 'r>: Sized + Signature {
    fn unmarshal(
        byteorder: ByteOrder,
        buf: &'buf [u8],
        offset: usize
    ) -> UnmarshalResult<Self>; }

This trait has to be supported to get parameters ergonomically out of a MarshalledMessage. There are implementations for the base types, Vecs, Hashmaps, and tuples of up to 5 elements if the contained types are Unmarshal. If you deal with basic messages, this should cover all your needs and you dont need to implement this type for your own types.

Implementing for your own structs

You can of course add your own implementations for you your own types. For this to work properly the signature must be correct and you need to report all bytes you consumed in the T::unmarshal(...) call. THIS INCLUDES PADDING.

Typically your code should look like this, keeping track of all padding and adjusting the local offset appropriatly

struct MyStruct{ mycoolint: u64}
use rustbus::wire::marshal::traits::Signature;
use rustbus::signature;
impl Signature for MyStruct {
    fn signature() -> signature::Type {
        signature::Type::Container(signature::Container::Struct(vec![
            u64::signature(),
        ]))
    }

    fn alignment() -> usize {
        8
    }
}  
use rustbus::wire::unmarshal::traits::Unmarshal;
use rustbus::wire::unmarshal::UnmarshalResult;
use rustbus::wire::util;
use rustbus::ByteOrder;
impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for MyStruct {
    fn unmarshal(
        byteorder: ByteOrder,
        buf: &'buf [u8],
        offset: usize,
    ) -> UnmarshalResult<Self> {
        // check that we are aligned properly
        let padding = util::align_offset(Self::alignment(), buf, offset)?;
        let offset = offset + padding;

        // decode some stuff and adjust offset
        let (bytes, mycoolint) = u64::unmarshal(byteorder, buf, offset)?;
        let offset = offset + bytes;
         
        // some more decoding if the struct had more fields
        // let padding2 = util::align_offset(u64::alignment(), buf, offset)?;
        // let offset = offset + padding2;
        // ect, etc
        Ok((padding + bytes /* + padding2  + more_bytes + ...*/, MyStruct{mycoolint}))
    }
}

This is of course just an example, this could be solved by using

This example is not tested
let (bytes, mycoolint) =  <(u64,) as Unmarshal>::unmarshal(...)

Cool things you can do

If the message contains some form of secondary marshalling, of another format, you can do this here too, insteadof copying the bytes array around before doing the secondary unmarshalling. Just keep in mind that you have to report the accurat number of bytes used, and not to use any bytes in the message, not belonging to that byte array

This example is not tested
impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for MyStruct {
    fn unmarshal(
        byteorder: ByteOrder,
        buf: &'buf [u8],
        offset: usize,
    ) -> UnmarshalResult<Self> {
        // check that we are aligned properly
        let padding = util::align_offset(Self::alignment(), buf, offset)?;
        let offset = offset + padding;

        // decode array length stuff and adjust offset
        let (bytes, arraylen) = u32::unmarshal(byteorder, buf, offset)?;
        let offset = offset + bytes;
        let marshalled_stuff = &buf[offset..arraylen as usize];
        let unmarshalled_stuff = external_crate::unmarshal_stuff(&buf);
        Ok((padding + bytes + arraylen as usize, MyStruct{unmarshalled_stuff}))
    }
}

Required methods

fn unmarshal(
    byteorder: ByteOrder,
    buf: &'buf [u8],
    offset: usize
) -> UnmarshalResult<Self>

Loading content...

Implementations on Foreign Types

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for ()[src]

impl<'r, 'buf: 'r, E1> Unmarshal<'r, 'buf> for (E1,) where
    E1: Unmarshal<'r, 'buf> + Sized
[src]

impl<'r, 'buf: 'r, E1, E2> Unmarshal<'r, 'buf> for (E1, E2) where
    E1: Unmarshal<'r, 'buf> + Sized,
    E2: Unmarshal<'r, 'buf> + Sized
[src]

impl<'r, 'buf: 'r, E1, E2, E3> Unmarshal<'r, 'buf> for (E1, E2, E3) where
    E1: Unmarshal<'r, 'buf> + Sized,
    E2: Unmarshal<'r, 'buf> + Sized,
    E3: Unmarshal<'r, 'buf> + Sized
[src]

impl<'r, 'buf: 'r, E1, E2, E3, E4> Unmarshal<'r, 'buf> for (E1, E2, E3, E4) where
    E1: Unmarshal<'r, 'buf> + Sized,
    E2: Unmarshal<'r, 'buf> + Sized,
    E3: Unmarshal<'r, 'buf> + Sized,
    E4: Unmarshal<'r, 'buf> + Sized
[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for u64[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for u32[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for u16[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for i64[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for i32[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for i16[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for u8[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for bool[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for &'r str[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for String[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for &'r [u8][src]

for byte arrays we can give an efficient method of decoding. This will bind the returned slice to the lifetime of the buffer.

impl<'r, 'buf: 'r, E: Unmarshal<'r, 'buf>> Unmarshal<'r, 'buf> for Vec<E>[src]

impl<'r, 'buf: 'r, K: Unmarshal<'r, 'buf> + Hash + Eq, V: Unmarshal<'r, 'buf>> Unmarshal<'r, 'buf> for HashMap<K, V>[src]

Loading content...

Implementors

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for ObjectPath<'r>[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for SignatureWrapper<'r>[src]

impl<'r, 'buf: 'r> Unmarshal<'r, 'buf> for UnixFd[src]

Loading content...