Trait async_rustbus::rustbus_core::wire::marshal::traits::Marshal[][src]

pub trait Marshal: Signature {
    fn marshal(&self, ctx: &mut MarshalContext<'_, '_>) -> Result<(), Error>;

    fn marshal_as_variant(
        &self,
        ctx: &mut MarshalContext<'_, '_>
    ) -> Result<(), Error> { ... } }
Expand description

The Marshal trait allows to push any type onto an message_builder::OutMessage as a parameter. There are some useful implementations here for slices and hashmaps which map to arrays and dicts in the dbus message.

The way dbus structs are represented is with rust tuples. This lib provides Marshal impls for tuples with up to 5 elements. If you need more you can just copy the impl and extend it to how many different entries you need.

There is a crate (rustbus_derive) for deriving Marshal 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 Marshal for your own structs:

struct MyStruct {
    x: u64,
    y: String,
}

use rustbus::ByteOrder;
use rustbus::signature;
use rustbus::wire::util;
use rustbus::Marshal;
use rustbus::wire::marshal::MarshalContext;
use rustbus::wire::marshal::traits::SignatureBuffer;
use rustbus::Signature;
impl Signature for &MyStruct {
    fn signature() -> signature::Type {
        signature::Type::Container(signature::Container::Struct(signature::StructTypes::new(vec![
            u64::signature(),
            String::signature(),
        ]).unwrap()))
    }

    fn alignment() -> usize {
        8
    }
    fn sig_str(s_buf: &mut SignatureBuffer) {
        s_buf.push_static("(ts)");
    }
    fn has_sig(sig: &str) -> bool {
        sig == "(ts)"
    }
}    
impl Marshal for &MyStruct {
    fn marshal(
        &self,
        ctx: &mut MarshalContext,
    ) -> Result<(), rustbus::Error> {
        // always align to 8 at the start of a struct!
        ctx.align_to(8);
        self.x.marshal(ctx)?;
        self.y.marshal(ctx)?;
        Ok(())
    }
}

Implementing for your own structs

There are some rules you need to follow, or the messages will be malformed:

  1. Structs need to be aligned to 8 bytes. Use ctx.align_to(8); to do that. If your type is marshalled as a primitive type you still need to align to that types alignment.
  2. If you write your own dict type, you need to align every key-value pair at 8 bytes like a struct
  3. The signature needs to be correct, or the message will be malformed
  4. The alignment must report the correct number. This does not need to be a constant like in the example, but it needs to be consistent with the type the signature() function returns. If you are not sure, just use Self::signature().get_alignment().

Required methods

Provided methods

Implementations on Foreign Types

Implementors