use crate::params;
use crate::wire::marshal::base::marshal_base_param;
use crate::wire::marshal::MarshalContext;
pub trait Marshal: Signature {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error>;
fn marshal_as_variant(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
let mut sig = SignatureBuffer::new();
Self::sig_str(&mut sig);
if sig.len() > 255 {
let sig_err = crate::signature::Error::SignatureTooLong;
return Err(sig_err.into());
}
debug_assert!(crate::params::validation::validate_signature(&sig).is_ok());
crate::wire::util::write_signature(&sig, ctx.buf);
self.marshal(ctx)
}
}
#[derive(Debug)]
pub struct SignatureBuffer(Cow<'static, str>);
impl SignatureBuffer {
#[inline]
pub fn new() -> Self {
Self(Cow::Borrowed(""))
}
#[inline]
pub fn push_static(&mut self, sig: &'static str) {
match &mut self.0 {
Cow::Borrowed("") => self.0 = Cow::Borrowed(sig),
Cow::Owned(s) if s.capacity() == 0 => self.0 = Cow::Borrowed(sig),
cow => cow.to_mut().push_str(sig),
}
}
#[inline]
pub fn push_str(&mut self, sig: &str) {
self.0.to_mut().push_str(sig);
}
#[inline]
pub fn to_string_mut(&mut self) -> &mut String {
self.0.to_mut()
}
#[inline]
pub fn clear(&mut self) {
match &mut self.0 {
Cow::Borrowed(_) => *self = Self::new(),
Cow::Owned(s) => s.clear(),
}
}
#[inline]
pub fn from_string(sig: String) -> Self {
Self(Cow::Owned(sig))
}
#[inline]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl std::ops::Deref for SignatureBuffer {
type Target = str;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_str()
}
}
impl AsRef<str> for SignatureBuffer {
#[inline]
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Default for SignatureBuffer {
#[inline]
fn default() -> Self {
Self::new()
}
}
use std::borrow::Cow;
pub trait Signature {
fn signature() -> crate::signature::Type;
fn alignment() -> usize;
#[inline]
unsafe fn valid_slice(_bo: crate::ByteOrder) -> bool {
false
}
fn sig_str(s_buf: &mut SignatureBuffer) {
let s_buf = s_buf.to_string_mut();
let typ = Self::signature();
typ.to_str(s_buf);
}
}
impl<S: Signature> Signature for &S {
fn signature() -> crate::signature::Type {
S::signature()
}
fn alignment() -> usize {
S::alignment()
}
}
impl<P: Marshal> Marshal for &P {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
(*self).marshal(ctx)
}
}
impl<E: Signature> Signature for (E,) {
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Struct(
crate::signature::StructTypes::new(vec![E::signature()]).unwrap(),
))
}
fn alignment() -> usize {
8
}
}
impl<E: Marshal> Marshal for (E,) {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(8);
self.0.marshal(ctx)?;
Ok(())
}
}
impl<E1: Signature, E2: Signature> Signature for (E1, E2) {
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Struct(
crate::signature::StructTypes::new(vec![E1::signature(), E2::signature()]).unwrap(),
))
}
fn alignment() -> usize {
8
}
fn sig_str(s_buf: &mut SignatureBuffer) {
s_buf.push_str("(");
E1::sig_str(s_buf);
E2::sig_str(s_buf);
s_buf.push_str(")");
}
}
impl<E1: Marshal, E2: Marshal> Marshal for (E1, E2) {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(8);
self.0.marshal(ctx)?;
self.1.marshal(ctx)?;
Ok(())
}
}
impl<E1: Signature, E2: Signature, E3: Signature> Signature for (E1, E2, E3) {
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Struct(
crate::signature::StructTypes::new(vec![
E1::signature(),
E2::signature(),
E3::signature(),
])
.unwrap(),
))
}
fn alignment() -> usize {
8
}
fn sig_str(s_buf: &mut SignatureBuffer) {
s_buf.push_str("(");
E1::sig_str(s_buf);
E2::sig_str(s_buf);
E3::sig_str(s_buf);
s_buf.push_str(")");
}
}
impl<E1: Marshal, E2: Marshal, E3: Marshal> Marshal for (E1, E2, E3) {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(8);
self.0.marshal(ctx)?;
self.1.marshal(ctx)?;
self.2.marshal(ctx)?;
Ok(())
}
}
impl<E1: Signature, E2: Signature, E3: Signature, E4: Signature> Signature for (E1, E2, E3, E4) {
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Struct(
crate::signature::StructTypes::new(vec![
E1::signature(),
E2::signature(),
E3::signature(),
E4::signature(),
])
.unwrap(),
))
}
fn alignment() -> usize {
8
}
fn sig_str(s_buf: &mut SignatureBuffer) {
s_buf.push_str("(");
E1::sig_str(s_buf);
E2::sig_str(s_buf);
E3::sig_str(s_buf);
E4::sig_str(s_buf);
s_buf.push_str(")");
}
}
impl<E1: Marshal, E2: Marshal, E3: Marshal, E4: Marshal> Marshal for (E1, E2, E3, E4) {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(8);
self.0.marshal(ctx)?;
self.1.marshal(ctx)?;
self.2.marshal(ctx)?;
self.3.marshal(ctx)?;
Ok(())
}
}
impl<E1: Signature, E2: Signature, E3: Signature, E4: Signature, E5: Signature> Signature
for (E1, E2, E3, E4, E5)
{
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Struct(
crate::signature::StructTypes::new(vec![
E1::signature(),
E2::signature(),
E3::signature(),
E4::signature(),
E5::signature(),
])
.unwrap(),
))
}
fn alignment() -> usize {
8
}
fn sig_str(s_buf: &mut SignatureBuffer) {
s_buf.push_str("(");
E1::sig_str(s_buf);
E2::sig_str(s_buf);
E3::sig_str(s_buf);
E4::sig_str(s_buf);
E5::sig_str(s_buf);
s_buf.push_str(")");
}
}
impl<E1: Marshal, E2: Marshal, E3: Marshal, E4: Marshal, E5: Marshal> Marshal
for (E1, E2, E3, E4, E5)
{
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(8);
self.0.marshal(ctx)?;
self.1.marshal(ctx)?;
self.2.marshal(ctx)?;
self.3.marshal(ctx)?;
self.4.marshal(ctx)?;
Ok(())
}
}
impl<E: Marshal> Marshal for Vec<E> {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
self.as_slice().marshal(ctx)
}
}
impl<E: Signature> Signature for [E] {
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Array(Box::new(
E::signature(),
)))
}
#[inline]
fn alignment() -> usize {
4
}
fn sig_str(s_buf: &mut SignatureBuffer) {
s_buf.push_str("a");
E::sig_str(s_buf);
}
}
impl<E: Marshal> Marshal for [E] {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
(&self).marshal(ctx)
}
}
impl<E: Signature> Signature for &[E] {
#[inline]
fn signature() -> crate::signature::Type {
<[E]>::signature()
}
#[inline]
fn alignment() -> usize {
<[E]>::alignment()
}
#[inline]
fn sig_str(s_buf: &mut SignatureBuffer) {
<[E]>::sig_str(s_buf)
}
}
use crate::wire::util::write_u32;
impl<E: Marshal> Marshal for &[E] {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(4);
let alignment = E::alignment();
unsafe {
if E::valid_slice(ctx.byteorder) {
debug_assert_eq!(alignment, std::mem::size_of::<E>());
let len = alignment * self.len();
assert!(len <= u32::MAX as usize);
write_u32(len as u32, ctx.byteorder, ctx.buf);
ctx.align_to(alignment);
let ptr = *self as *const [E] as *const u8;
let slice = std::slice::from_raw_parts(ptr, len);
ctx.buf.extend_from_slice(slice);
return Ok(());
}
}
let size_pos = ctx.buf.len();
ctx.buf.extend_from_slice(&[0; 4]);
ctx.align_to(alignment);
if self.is_empty() {
return Ok(());
}
ctx.buf.reserve(self.len() * alignment);
let size_before = ctx.buf.len();
for p in self.iter() {
p.marshal(ctx)?;
}
let size_of_content = ctx.buf.len() - size_before;
crate::wire::util::insert_u32(
ctx.byteorder,
size_of_content as u32,
&mut ctx.buf[size_pos..size_pos + 4],
);
Ok(())
}
}
pub struct OptimizedMarshal<'a, E: Copy + Marshal>(pub &'a [E]);
impl<'a, E: Copy + Marshal> Signature for OptimizedMarshal<'a, E> {
fn signature() -> crate::signature::Type {
crate::signature::Type::Container(crate::signature::Container::Array(Box::new(
E::signature(),
)))
}
fn alignment() -> usize {
4
}
}
impl<'a, E: Copy + Marshal> Marshal for OptimizedMarshal<'a, E> {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(4);
let size_pos = ctx.buf.len();
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.align_to(E::alignment());
if self.0.is_empty() {
return Ok(());
}
let size_of_content = std::mem::size_of::<E>() * self.0.len();
let len_before_resize = ctx.buf.len();
ctx.buf.resize(ctx.buf.len() + size_of_content, 0);
unsafe {
let content_ptr = ctx.buf.as_mut_ptr().add(len_before_resize);
std::ptr::copy_nonoverlapping(
self.0.as_ptr() as *const u8,
content_ptr,
size_of_content,
);
}
crate::wire::util::insert_u32(
ctx.byteorder,
size_of_content as u32,
&mut ctx.buf[size_pos..size_pos + 4],
);
Ok(())
}
}
#[test]
fn verify_optimized_arrays() {
use crate::wire::marshal::container::marshal_container_param;
use crate::ByteOrder;
let mut fds = Vec::new();
let mut buf = Vec::new();
let mut ctx = MarshalContext {
buf: &mut buf,
fds: &mut fds,
byteorder: ByteOrder::LittleEndian,
};
let ctx = &mut ctx;
let arru64: Vec<u64> = vec![1, 2, 3, 4, 5, 6, u64::MAX, u64::MAX / 2, u64::MAX / 1024];
let mut buf_normal = Vec::new();
ctx.buf = &mut buf_normal;
arru64.as_slice().marshal(ctx).unwrap();
let mut buf_optimized = Vec::new();
ctx.buf = &mut buf_optimized;
OptimizedMarshal(arru64.as_slice()).marshal(ctx).unwrap();
assert_eq!(buf_normal, buf_optimized);
let mut ctx = MarshalContext {
buf: &mut buf,
fds: &mut fds,
byteorder: ByteOrder::LittleEndian,
};
let ctx = &mut ctx;
let mut buf_normal = Vec::new();
ctx.buf = &mut buf_normal;
let arru8: Vec<u8> = vec![1, 2, 3, 4, 5, 6, 255, 128, 80, 180];
arru8.as_slice().marshal(ctx).unwrap();
let mut buf_optimized = Vec::new();
ctx.buf = &mut buf_optimized;
OptimizedMarshal(arru8.as_slice()).marshal(ctx).unwrap();
assert_eq!(buf_normal, buf_optimized);
let mut ctx = MarshalContext {
buf: &mut buf,
fds: &mut fds,
byteorder: ByteOrder::LittleEndian,
};
let ctx = &mut ctx;
let empty: Vec<u8> = Vec::new();
let x = crate::params::Container::make_array("y", empty.clone().into_iter()).unwrap();
let mut buf_normal = Vec::new();
ctx.buf = &mut buf_normal;
empty.as_slice().marshal(ctx).unwrap();
let mut buf_optimized = Vec::new();
ctx.buf = &mut buf_optimized;
OptimizedMarshal(empty.as_slice()).marshal(ctx).unwrap();
let mut buf_old = Vec::new();
ctx.buf = &mut buf_old;
marshal_container_param(&x, ctx).unwrap();
assert_eq!(buf_normal, buf_optimized);
assert_eq!(buf_normal, buf_old);
assert_eq!(vec![0, 0, 0, 0], buf_old);
}
impl<K: Signature, V: Signature> Signature for std::collections::HashMap<K, V> {
fn signature() -> crate::signature::Type {
let ks = K::signature();
let vs = V::signature();
if let crate::signature::Type::Base(ks) = ks {
crate::signature::Type::Container(crate::signature::Container::Dict(ks, Box::new(vs)))
} else {
panic!("Ivalid key sig")
}
}
fn alignment() -> usize {
4
}
}
impl<K: Marshal, V: Marshal> Marshal for std::collections::HashMap<K, V> {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(4);
let size_pos = ctx.buf.len();
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.buf.push(0);
ctx.align_to(8);
if self.is_empty() {
return Ok(());
}
let size_before = ctx.buf.len();
for p in self.iter() {
ctx.align_to(8);
p.0.marshal(ctx)?;
p.1.marshal(ctx)?;
}
let size_of_content = ctx.buf.len() - size_before;
crate::wire::util::insert_u32(
ctx.byteorder,
size_of_content as u32,
&mut ctx.buf[size_pos..size_pos + 4],
);
Ok(())
}
}
impl Signature for u64 {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Uint64)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(bo: crate::ByteOrder) -> bool {
bo == crate::ByteOrder::NATIVE
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("t");
}
}
impl Marshal for u64 {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
let b: params::Base = self.into();
marshal_base_param(&b, ctx)
}
}
impl Signature for i64 {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Int64)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(bo: crate::ByteOrder) -> bool {
bo == crate::ByteOrder::NATIVE
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("x");
}
}
impl Marshal for i64 {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
let b: params::Base = self.into();
marshal_base_param(&b, ctx)
}
}
impl Signature for u32 {
#[inline]
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Uint32)
}
#[inline]
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(bo: crate::ByteOrder) -> bool {
bo == crate::ByteOrder::NATIVE
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("u");
}
}
impl Marshal for u32 {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
crate::wire::util::write_u32(*self, ctx.byteorder, ctx.buf);
Ok(())
}
}
impl Signature for i32 {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Int32)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(bo: crate::ByteOrder) -> bool {
bo == crate::ByteOrder::NATIVE
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("i");
}
}
impl Marshal for i32 {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
crate::wire::util::write_u32(*self as u32, ctx.byteorder, ctx.buf);
Ok(())
}
}
impl Signature for u16 {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Uint16)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(bo: crate::ByteOrder) -> bool {
bo == crate::ByteOrder::NATIVE
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("q");
}
}
impl Marshal for u16 {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
let b: params::Base = self.into();
marshal_base_param(&b, ctx)
}
}
impl Signature for i16 {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Int16)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(bo: crate::ByteOrder) -> bool {
bo == crate::ByteOrder::NATIVE
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("n");
}
}
impl Marshal for i16 {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
let b: params::Base = self.into();
marshal_base_param(&b, ctx)
}
}
impl Signature for u8 {
#[inline]
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Byte)
}
#[inline]
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
unsafe fn valid_slice(_: crate::ByteOrder) -> bool {
true
}
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("y");
}
}
impl Marshal for u8 {
#[inline]
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.buf.push(*self);
Ok(())
}
}
impl Signature for bool {
#[inline]
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Boolean)
}
#[inline]
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("b");
}
}
impl Marshal for bool {
#[inline]
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
(*self as u32).marshal(ctx)
}
}
impl Signature for String {
#[inline]
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::String)
}
#[inline]
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
fn sig_str(sig: &mut SignatureBuffer) {
sig.push_static("s");
}
}
impl Marshal for String {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
self.as_str().marshal(ctx)
}
}
impl Signature for &str {
#[inline]
fn signature() -> crate::signature::Type {
String::signature()
}
#[inline]
fn alignment() -> usize {
String::alignment()
}
#[inline]
fn sig_str(sig: &mut SignatureBuffer) {
String::sig_str(sig);
}
}
impl Marshal for &str {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
ctx.align_to(Self::alignment());
crate::wire::util::write_string(self, ctx.byteorder, ctx.buf);
Ok(())
}
}
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
pub struct ObjectPath<S: AsRef<str>>(S);
impl<S: AsRef<str>> ObjectPath<S> {
pub fn new(path: S) -> Result<Self, crate::params::validation::Error> {
crate::params::validate_object_path(path.as_ref())?;
Ok(ObjectPath(path))
}
pub fn to_owned(&self) -> ObjectPath<String> {
ObjectPath(self.as_ref().to_owned())
}
}
impl<S: AsRef<str>> AsRef<str> for ObjectPath<S> {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl<S: AsRef<str>> Signature for ObjectPath<S> {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::ObjectPath)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
}
impl<S: AsRef<str>> Marshal for ObjectPath<S> {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
self.0.as_ref().marshal(ctx)
}
}
#[derive(Debug, PartialEq)]
pub struct SignatureWrapper<'a>(&'a str);
impl<'a> SignatureWrapper<'a> {
pub fn new(sig: &'a str) -> Result<Self, crate::params::validation::Error> {
crate::params::validate_signature(sig)?;
Ok(SignatureWrapper(sig))
}
}
impl<'a> AsRef<str> for SignatureWrapper<'a> {
fn as_ref(&self) -> &str {
self.0
}
}
impl Signature for SignatureWrapper<'_> {
fn signature() -> crate::signature::Type {
crate::signature::Type::Base(crate::signature::Base::Signature)
}
fn alignment() -> usize {
Self::signature().get_alignment()
}
#[inline]
fn sig_str(s_buf: &mut SignatureBuffer) {
s_buf.push_static("g");
}
}
impl Marshal for SignatureWrapper<'_> {
fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), crate::Error> {
crate::wire::util::write_signature(self.0, ctx.buf);
Ok(())
}
}
#[test]
fn test_trait_signature_creation() {
let mut msg = crate::message_builder::MarshalledMessage::new();
let body = &mut msg.body;
body.push_param("a").unwrap();
body.push_param(ObjectPath::new("/a/b").unwrap()).unwrap();
body.push_param(SignatureWrapper::new("(a{su})").unwrap())
.unwrap();
let fd = crate::wire::UnixFd::new(nix::unistd::dup(1).unwrap());
body.push_param(&fd).unwrap();
body.push_param(true).unwrap();
body.push_param(0u8).unwrap();
body.push_param(0u16).unwrap();
body.push_param(0u32).unwrap();
body.push_param(0u64).unwrap();
body.push_param(0i16).unwrap();
body.push_param(0i32).unwrap();
body.push_param(0i64).unwrap();
body.push_param(&[0u8][..]).unwrap();
let map: std::collections::HashMap<String, (u64, u32, u16, u8)> =
std::collections::HashMap::new();
body.push_param(&map).unwrap();
assert_eq!("soghbyqutnixaya{s(tuqy)}", msg.get_sig());
}
#[test]
fn test_empty_array_padding() {
use crate::wire::marshal::container::marshal_container_param;
let mut msg = crate::message_builder::MarshalledMessage::new();
let body = &mut msg.body;
let empty = vec![0u64; 0];
body.push_param(&empty[..]).unwrap();
let empty = crate::params::Container::make_array_with_sig(
crate::signature::Type::Base(crate::signature::Base::Uint64),
empty.into_iter(),
)
.unwrap();
let mut fds = Vec::new();
let mut buf = Vec::new();
let mut ctx = MarshalContext {
fds: &mut fds,
buf: &mut buf,
byteorder: crate::ByteOrder::LittleEndian,
};
marshal_container_param(&empty, &mut ctx).unwrap();
assert_eq!(msg.get_buf(), &[0, 0, 0, 0, 0, 0, 0, 0]);
assert_eq!(buf.as_slice(), &[0, 0, 0, 0, 0, 0, 0, 0]);
}
#[test]
fn test_variant_marshalling() {
let mut msg = crate::message_builder::MarshalledMessage::new();
let body = &mut msg.body;
let original = (100u64, "ABCD", true);
body.push_variant(original).unwrap();
assert_eq!(
msg.get_buf(),
&[
5, b'(', b't', b's', b'b', b')', b'\0', 0, 100, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, b'A',
b'B', b'C', b'D', b'\0', 0, 0, 0, 1, 0, 0, 0
]
)
}