Trait rustbus::wire::unmarshal::traits::Unmarshal [−][src]
pub trait Unmarshal<'buf, 'fds>: Sized + Signature { fn unmarshal(
ctx: &mut UnmarshalContext<'fds, 'buf>
) -> 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.
There is a crate (rustbus_derive) for deriving Unmarshal impls with #[derive(rustbus_derive::Marshal)]. This should work for most of your needs. You can of course derive Signature as well.
If there are special needs, you can implement Unmarshal for your own structs:
Implementing for your own structs
You can of course add your own implementations for 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:
struct MyStruct{ mycoolint: u64} use rustbus::wire::marshal::traits::Signature; use rustbus::wire::unmarshal::UnmarshalContext; use rustbus::wire::unmarshal; use rustbus::signature; impl Signature for MyStruct { fn signature() -> signature::Type { signature::Type::Container(signature::Container::Struct(signature::StructTypes::new(vec![ u64::signature(), ]).unwrap())) } fn alignment() -> usize { 8 } } use rustbus::wire::unmarshal::traits::Unmarshal; use rustbus::wire::unmarshal::UnmarshalResult; use rustbus::wire::util; use rustbus::ByteOrder; impl<'buf, 'fds> Unmarshal<'buf, 'fds> for MyStruct { fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> unmarshal::UnmarshalResult<Self> { let start_offset = ctx.offset; // check that we are aligned properly! // This is necessary at the start of each struct! They need to be aligned to 8 bytes! let padding = ctx.align_to(Self::alignment())?; // decode some stuff and adjust offset let (bytes, mycoolint) = u64::unmarshal(ctx)?; // some more decoding if the struct had more fields // .... //then report the total bytes used by unmarshalling this type (INCLUDING padding at the beginning!): let total_bytes = ctx.offset - start_offset; Ok((total_bytes, MyStruct{mycoolint})) } }
This is of course just an example, this could be solved by using
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, instead of copying the bytes array around before doing the secondary unmarshalling. Just keep in mind that you have to report the accurate number of bytes used, and not to use any bytes in the message, not belonging to that byte array
As an example, lets assume your message contains a byte-array that is actually json data. Then you can use serde_json to unmarshal that array directly here without having to do a separate step for that.
impl<'r, 'buf: 'r, 'fds> Unmarshal<'r, 'buf, 'fds> for MyStruct { fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> unmarshal::UnmarshalResult<Self> { let start_offset = ctx.offset; // check that we are aligned properly let padding = ctx.align_to(Self::alignment())?; // get the slice that contains marshalled data, and unmarshal it directly here! let (bytes, raw_data) = <&[u8] as Unmarshal>::unmarshal(ctx)?; let unmarshalled_stuff = external_crate::unmarshal_stuff(&raw_data); //then report the total bytes used by unmarshalling this type (INCLUDING padding at the beginning!): let total_bytes = ctx.offset - start_offset; Ok((total_bytes, MyStruct{unmarshalled_stuff})) } }
Required methods
fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
Implementations on Foreign Types
impl<'buf, 'fds, E1> Unmarshal<'buf, 'fds> for (E1,) where
E1: Unmarshal<'buf, 'fds> + Sized,
[src]
impl<'buf, 'fds, E1> Unmarshal<'buf, 'fds> for (E1,) where
E1: Unmarshal<'buf, 'fds> + Sized,
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, E1, E2> Unmarshal<'buf, 'fds> for (E1, E2) where
E1: Unmarshal<'buf, 'fds> + Sized,
E2: Unmarshal<'buf, 'fds> + Sized,
[src]
impl<'buf, 'fds, E1, E2> Unmarshal<'buf, 'fds> for (E1, E2) where
E1: Unmarshal<'buf, 'fds> + Sized,
E2: Unmarshal<'buf, 'fds> + Sized,
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, E1, E2, E3> Unmarshal<'buf, 'fds> for (E1, E2, E3) where
E1: Unmarshal<'buf, 'fds> + Sized,
E2: Unmarshal<'buf, 'fds> + Sized,
E3: Unmarshal<'buf, 'fds> + Sized,
[src]
impl<'buf, 'fds, E1, E2, E3> Unmarshal<'buf, 'fds> for (E1, E2, E3) where
E1: Unmarshal<'buf, 'fds> + Sized,
E2: Unmarshal<'buf, 'fds> + Sized,
E3: Unmarshal<'buf, 'fds> + Sized,
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, E1, E2, E3, E4> Unmarshal<'buf, 'fds> for (E1, E2, E3, E4) where
E1: Unmarshal<'buf, 'fds> + Sized,
E2: Unmarshal<'buf, 'fds> + Sized,
E3: Unmarshal<'buf, 'fds> + Sized,
E4: Unmarshal<'buf, 'fds> + Sized,
[src]
impl<'buf, 'fds, E1, E2, E3, E4> Unmarshal<'buf, 'fds> for (E1, E2, E3, E4) where
E1: Unmarshal<'buf, 'fds> + Sized,
E2: Unmarshal<'buf, 'fds> + Sized,
E3: Unmarshal<'buf, 'fds> + Sized,
E4: Unmarshal<'buf, 'fds> + Sized,
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u64
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u64
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u32
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u32
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u16
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u16
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for i64
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for i64
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for i32
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for i32
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for i16
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for i16
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u8
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for u8
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for bool
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for bool
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for &'buf str
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for &'buf str
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for String
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for String
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for &'buf [u8]
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for &'buf [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.
fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, E: Unmarshal<'buf, 'fds> + Clone> Unmarshal<'buf, 'fds> for Cow<'buf, [E]>
[src]
impl<'buf, 'fds, E: Unmarshal<'buf, 'fds> + Clone> Unmarshal<'buf, 'fds> for Cow<'buf, [E]>
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, E: Unmarshal<'buf, 'fds>> Unmarshal<'buf, 'fds> for Vec<E>
[src]
impl<'buf, 'fds, E: Unmarshal<'buf, 'fds>> Unmarshal<'buf, 'fds> for Vec<E>
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, K: Unmarshal<'buf, 'fds> + Hash + Eq, V: Unmarshal<'buf, 'fds>> Unmarshal<'buf, 'fds> for HashMap<K, V>
[src]
impl<'buf, 'fds, K: Unmarshal<'buf, 'fds> + Hash + Eq, V: Unmarshal<'buf, 'fds>> Unmarshal<'buf, 'fds> for HashMap<K, V>
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
Implementors
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for SignatureWrapper<'buf>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for SignatureWrapper<'buf>
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for UnixFd
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for UnixFd
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for Variant<'fds, 'buf>
[src]
impl<'buf, 'fds> Unmarshal<'buf, 'fds> for Variant<'fds, 'buf>
[src]fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> UnmarshalResult<Self>
[src]
impl<'buf, 'fds, S: AsRef<str> + Unmarshal<'buf, 'fds>> Unmarshal<'buf, 'fds> for ObjectPath<S>
[src]
impl<'buf, 'fds, S: AsRef<str> + Unmarshal<'buf, 'fds>> Unmarshal<'buf, 'fds> for ObjectPath<S>
[src]