pub struct Body<'a> { /* private fields */ }Expand description
A read-only view into a buffer suitable for use as a body in a Message.
§Examples
use tokio_dbus::{Result, Body};
fn read(buf: &mut Body<'_>) -> Result<()> {
assert_eq!(buf.load::<u32>()?, 7u32);
assert_eq!(buf.load::<u8>()?, b'f');
assert_eq!(buf.load::<u8>()?, b'o');
assert_eq!(buf.get(), &[b'o', b' ', b'b', b'a', b'r', 0]);
Ok(())
}Implementations§
Source§impl<'a> Body<'a>
impl<'a> Body<'a>
Sourcepub fn endianness(&self) -> Endianness
pub fn endianness(&self) -> Endianness
Get the endianness of the buffer.
§Examples
use tokio_dbus::{Body, BodyBuf, Endianness};
let buf = BodyBuf::new();
let buf: Body<'_> = buf.as_body();
assert_eq!(buf.endianness(), Endianness::NATIVE);
let buf = buf.with_endianness(Endianness::BIG);
assert_eq!(buf.endianness(), Endianness::BIG);Sourcepub fn with_endianness(self, endianness: Endianness) -> Self
pub fn with_endianness(self, endianness: Endianness) -> Self
Adjust endianness of buffer.
§Examples
use tokio_dbus::{Body, BodyBuf, Endianness};
let buf = BodyBuf::new();
let buf: Body<'_> = buf.as_body();
assert_eq!(buf.endianness(), Endianness::NATIVE);
let buf = buf.with_endianness(Endianness::BIG);
assert_eq!(buf.endianness(), Endianness::BIG);Sourcepub fn signature(&self) -> &'a Signature
pub fn signature(&self) -> &'a Signature
Get the signature of the buffer.
§Examples
use tokio_dbus::{Body, BodyBuf};
let mut buf = BodyBuf::new();
buf.store(10u16)?;
buf.store(10u32)?;
let buf: Body<'_> = buf.as_body();
assert_eq!(buf.signature(), "qu");Sourcepub fn get(&self) -> &'a [u8] ⓘ
pub fn get(&self) -> &'a [u8] ⓘ
Get a slice out of the buffer that has ben written to.
§Examples
use tokio_dbus::{Result, Body};
fn read(buf: &mut Body<'_>) -> Result<()> {
assert_eq!(buf.load::<u32>()?, 7u32);
assert_eq!(buf.load::<u8>()?, b'f');
assert_eq!(buf.load::<u8>()?, b'o');
assert_eq!(buf.get(), &[b'o', b' ', b'b', b'a', b'r', 0]);
Ok(())
}Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Test if the buffer is empty.
§Examples
use tokio_dbus::{Body, BodyBuf, Endianness};
let mut buf = BodyBuf::with_endianness(Endianness::LITTLE);
let b: Body<'_> = buf.as_body();
assert!(b.is_empty());
buf.store(10u16)?;
buf.store(10u32)?;
let b: Body<'_> = buf.as_body();
assert!(!b.is_empty());Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Remaining data to be read from the buffer.
§Examples
use tokio_dbus::{Body, BodyBuf, Endianness};
let mut buf = BodyBuf::with_endianness(Endianness::LITTLE);
assert!(buf.is_empty());
buf.store(10u16)?;
buf.store(10u32)?;
let b: Body<'_> = buf.as_body();
assert_eq!(b.len(), 8);Sourcepub fn read<T>(&mut self) -> Result<&'a T>
pub fn read<T>(&mut self) -> Result<&'a T>
Read a reference from the buffer.
This is possible for unaligned types such as str and [u8] which
implement Read.
§Examples
use tokio_dbus::{Result, Body};
fn read(buf: &mut Body<'_>) -> Result<()> {
assert_eq!(buf.load::<u32>()?, 4);
assert_eq!(buf.read::<str>()?, "hi");
assert!(buf.is_empty());
Ok(())
}Sourcepub fn read_until(&mut self, len: usize) -> Body<'a>
pub fn read_until(&mut self, len: usize) -> Body<'a>
Read len bytes from the buffer and make accessible through another
Body instance constituting that sub-slice.
§Panics
This panics if len is larger than len().
§Examples
use tokio_dbus::{Result, Body};
fn read(buf: &mut Body<'_>) -> Result<()> {
let mut read_buf = buf.read_until(6);
assert_eq!(read_buf.load::<u32>()?, 4);
let mut read_buf2 = read_buf.read_until(2);
assert_eq!(read_buf2.load::<u8>()?, 1);
assert_eq!(read_buf2.load::<u8>()?, 2);
assert!(read_buf.is_empty());
assert!(read_buf2.is_empty());
assert_eq!(buf.get(), &[3, 4, 0]);
Ok(())
}Sourcepub fn load_array<E>(&mut self) -> Result<LoadArray<'a, E>>where
E: Marker,
pub fn load_array<E>(&mut self) -> Result<LoadArray<'a, E>>where
E: Marker,
Read an array from the buffer.
§Examples
use tokio_dbus::{ty, BodyBuf, Endianness};
let mut buf = BodyBuf::with_endianness(Endianness::LITTLE);
let mut array = buf.store_array::<u32>()?;
array.store(10u32);
array.store(20u32);
array.store(30u32);
array.finish();
let mut array = buf.store_array::<ty::Array<ty::Str>>()?;
let mut inner = array.store_array();
inner.store("foo");
inner.store("bar");
inner.store("baz");
inner.finish();
array.finish();
assert_eq!(buf.signature(), b"auaas");
let mut buf = buf.as_body();
let mut array = buf.load_array::<u32>()?;
assert_eq!(array.load()?, Some(10));
assert_eq!(array.load()?, Some(20));
assert_eq!(array.load()?, Some(30));
assert_eq!(array.load()?, None);
let mut array = buf.load_array::<ty::Array<ty::Str>>()?;
let Some(mut inner) = array.load_array()? else {
panic!("Missing inner array");
};
assert_eq!(inner.read()?, Some("foo"));
assert_eq!(inner.read()?, Some("bar"));
assert_eq!(inner.read()?, Some("baz"));
assert_eq!(inner.read()?, None);Sourcepub fn load_struct<E>(&mut self) -> Result<E::Return<'a>>where
E: Fields,
pub fn load_struct<E>(&mut self) -> Result<E::Return<'a>>where
E: Fields,
Read a struct from the buffer.
§Examples
use tokio_dbus::{ty, BodyBuf, Endianness};
let mut buf = BodyBuf::with_endianness(Endianness::LITTLE);
buf.store(10u8);
buf.store_struct::<(u16, u32, ty::Array<u8>, ty::Str)>()?
.store(20u16)
.store(30u32)
.store_array(|w| {
w.store(1u8);
w.store(2u8);
w.store(3u8);
})
.store("Hello World")
.finish();
assert_eq!(buf.signature(), "y(quays)");
let mut buf = buf.as_body();
assert_eq!(buf.load::<u8>()?, 10u8);
let (a, b, mut array, string) = buf.load_struct::<(u16, u32, ty::Array<u8>, ty::Str)>()?;
assert_eq!(a, 20u16);
assert_eq!(b, 30u32);
assert_eq!(array.load()?, Some(1));
assert_eq!(array.load()?, Some(2));
assert_eq!(array.load()?, Some(3));
assert_eq!(array.load()?, None);
assert_eq!(string, "Hello World");Sourcepub fn load_struct_with<F, O>(&mut self, f: F) -> Result<O>
pub fn load_struct_with<F, O>(&mut self, f: F) -> Result<O>
Read a struct whose fields are read by the given closure.
This aligns the buffer as a struct and then hands it to f. It is an
escape hatch for structs which load_struct() cannot describe, such as
ones containing a variant of an unknown type.
§Examples
use tokio_dbus::{ty, BodyBuf, Signature};
let mut buf = BodyBuf::new();
buf.store_struct::<(u32, ty::Variant)>()?
.store(42u32)
.store_variant(Signature::new("as")?, |w| {
w.store_array::<ty::Str>().store("Hello");
})
.finish();
let mut buf = buf.as_body();
let n = buf.load_struct_with(|b| {
let n = b.load::<u32>()?;
b.skip_variant()?;
Ok(n)
})?;
assert_eq!(n, 42);Sourcepub fn load<T>(&mut self) -> Result<T>where
T: Frame,
pub fn load<T>(&mut self) -> Result<T>where
T: Frame,
Load a frame of the given type.
This advances the read cursor of the buffer by the alignment and size of
the type. The return value has been endian-adjusted as per
endianness().
§Error
Errors if the underlying buffer does not have enough space to represent
the type T.
§Examples
use tokio_dbus::{Result, Body};
fn read(buf: &mut Body<'_>) -> Result<()> {
assert_eq!(buf.load::<u32>()?, 7u32);
assert_eq!(buf.load::<u8>()?, b'f');
assert_eq!(buf.load::<u8>()?, b'o');
assert_eq!(buf.get(), &[b'o', b' ', b'b', b'a', b'r', 0]);
Ok(())
}Sourcepub fn load_bool(&mut self) -> Result<bool>
pub fn load_bool(&mut self) -> Result<bool>
Load a bool from the buffer.
The D-Bus BOOLEAN type is marshalled as a 32-bit integer, which is why
it cannot be loaded through load().
§Examples
use tokio_dbus::BodyBuf;
let mut buf = BodyBuf::new();
buf.store(true)?;
buf.store(false)?;
let mut buf = buf.as_body();
assert!(buf.load_bool()?);
assert!(!buf.load_bool()?);Sourcepub fn read_variant(&mut self) -> Result<Variant<'a>>
pub fn read_variant(&mut self) -> Result<Variant<'a>>
Read a Variant holding a value of a basic type from the buffer.
§Errors
Errors if the variant holds a container. Use skip_variant() to skip
over a variant of an unknown type instead.
§Examples
use tokio_dbus::{BodyBuf, Variant};
let mut buf = BodyBuf::new();
buf.store(Variant::U32(42))?;
let mut buf = buf.as_body();
assert_eq!(buf.read_variant()?, Variant::U32(42));Sourcepub fn read_variant_as<T>(&mut self) -> Result<T::Return<'a>>where
T: Marker,
pub fn read_variant_as<T>(&mut self) -> Result<T::Return<'a>>where
T: Marker,
Read a variant which is expected to contain a value of type T.
Unlike read_variant() this can read containers, but requires the
caller to know which type the variant contains.
§Errors
Errors if the variant does not contain a value of type T.
§Examples
use tokio_dbus::{ty, BodyBuf, Signature};
let mut buf = BodyBuf::new();
let mut array = buf.store_variant(Signature::new("as")?)?.store_array::<ty::Str>();
array.store("Hello");
array.store("World");
array.finish();
let mut buf = buf.as_body();
let mut array = buf.read_variant_as::<ty::Array<ty::Str>>()?;
assert_eq!(array.read()?, Some("Hello"));
assert_eq!(array.read()?, Some("World"));
assert_eq!(array.read()?, None);Sourcepub fn skip_variant(&mut self) -> Result<&'a Signature>
pub fn skip_variant(&mut self) -> Result<&'a Signature>
Skip over a variant of any type, returning the signature of the value it contained.
This is useful for arguments which are declared as variants but which
the receiver has no interest in, such as the data argument of the
com.canonical.dbusmenu.Event method.
§Examples
use tokio_dbus::{ty, BodyBuf, Signature};
let mut buf = BodyBuf::new();
buf.store_variant(Signature::new("as")?)?
.store_array::<ty::Str>()
.store("Hello");
buf.store(42u32)?;
assert_eq!(buf.signature(), "vu");
let mut buf = buf.as_body();
assert_eq!(buf.skip_variant()?, Signature::new("as")?);
assert_eq!(buf.load::<u32>()?, 42);Sourcepub fn align_to(&mut self, alignment: Alignment) -> Result<()>
pub fn align_to(&mut self, alignment: Alignment) -> Result<()>
Align the read cursor to the given alignment.
This is the counterpart of Raw::align, and is needed before reading
the fields of a struct or a dict entry whose shape is only known at
runtime.
§Examples
use tokio_dbus::{ty, Alignment, BodyBuf};
let mut buf = BodyBuf::new();
buf.store(1u8)?;
buf.store_struct::<(u32, u32)>()?.store(2u32).store(3u32).finish();
let mut buf = buf.as_body();
assert_eq!(buf.load::<u8>()?, 1);
buf.align_to(Alignment::U64)?;
assert_eq!(buf.load::<u32>()?, 2);
assert_eq!(buf.load::<u32>()?, 3);Sourcepub fn load_raw_array(&mut self, alignment: Alignment) -> Result<Body<'a>>
pub fn load_raw_array(&mut self, alignment: Alignment) -> Result<Body<'a>>
Read an array whose elements have the given alignment, returning a
Body over its contents.
This is the counterpart of Raw::store_array.
§Examples
use tokio_dbus::{ty, Alignment, BodyBuf};
let mut buf = BodyBuf::new();
let mut array = buf.store_array::<ty::Str>()?;
array.store("Hello");
array.store("World");
array.finish();
let mut buf = buf.as_body();
let mut array = buf.load_raw_array(Alignment::U32)?;
let mut out = Vec::new();
while !array.is_empty() {
out.push(array.read::<str>()?);
}
assert_eq!(out, ["Hello", "World"]);Trait Implementations§
Source§impl<'de> AsBody<'de> for &Body<'de>
impl<'de> AsBody<'de> for &Body<'de>
Since Body is cheap to clone, it doesn’t hurt to provide this coercions.
§Examples
use tokio_dbus::{BodyBuf, MessageKind, ObjectPath, SendBuf, Signature};
const PATH: &ObjectPath = ObjectPath::new_const(b"/org/freedesktop/DBus");
let mut send = SendBuf::new();
let mut body = BodyBuf::new();
body.store("Hello World!");
let m = send.method_call(PATH, "Hello")
.with_body(&body.as_body());
assert!(matches!(m.kind(), MessageKind::MethodCall { .. }));
assert_eq!(m.signature(), Signature::STRING);Source§impl<'de> AsBody<'de> for Body<'de>
impl<'de> AsBody<'de> for Body<'de>
§Examples
use tokio_dbus::{BodyBuf, MessageKind, ObjectPath, SendBuf, Signature};
const PATH: &ObjectPath = ObjectPath::new_const(b"/org/freedesktop/DBus");
let mut send = SendBuf::new();
let mut body = BodyBuf::new();
body.store("Hello World!");
let m = send.method_call(PATH, "Hello")
.with_body(body.as_body());
assert!(matches!(m.kind(), MessageKind::MethodCall { .. }));
assert_eq!(m.signature(), Signature::STRING);