1use zvariant::{
2 serialized::{self, Data},
3 Signature, Type,
4};
5
6use crate::{Error, Message, Result};
7
8/// The body of a message.
9///
10/// This contains the bytes and the signature of the body.
11#[derive(Clone, Debug)]
12pub struct Body {
13 data: Data<'static, 'static>,
14 msg: Message,
15}
16
17impl Body {
18 pub(super) fn new(data: Data<'static, 'static>, msg: Message) -> Self {
19 Self { data, msg }
20 }
21
22 /// Deserialize the body using the contained signature.
23 pub fn deserialize<'s, B>(&'s self) -> Result<B>
24 where
25 B: zvariant::DynamicDeserialize<'s>,
26 {
27 let body_sig = self
28 .signature()
29 .unwrap_or_else(|| Signature::from_static_str_unchecked(""));
30
31 self.data
32 .deserialize_for_dynamic_signature(body_sig)
33 .map_err(Error::from)
34 .map(|b| b.0)
35 }
36
37 /// Deserialize the body (without checking signature matching).
38 pub fn deserialize_unchecked<'d, 'm: 'd, B>(&'m self) -> Result<B>
39 where
40 B: serde::de::Deserialize<'d> + Type,
41 {
42 self.data.deserialize().map_err(Error::from).map(|b| b.0)
43 }
44
45 /// The signature of the body.
46 ///
47 /// **Note:** While zbus treats multiple arguments as a struct (to allow you to use the tuple
48 /// syntax), D-Bus does not. Since this method gives you the signature expected on the wire by
49 /// D-Bus, the trailing and leading STRUCT signature parenthesis will not be present in case of
50 /// multiple arguments.
51 pub fn signature(&self) -> Option<Signature<'_>> {
52 self.msg.inner.quick_fields.signature(&self.msg)
53 }
54
55 /// The length of the body in bytes.
56 pub fn len(&self) -> usize {
57 self.data.len()
58 }
59
60 /// Whether the body is empty.
61 pub fn is_empty(&self) -> bool {
62 self.data.is_empty()
63 }
64
65 /// Get a reference to the underlying byte encoding of the message.
66 pub fn data(&self) -> &serialized::Data<'static, 'static> {
67 &self.data
68 }
69
70 /// Reference to the message this body belongs to.
71 pub fn message(&self) -> &Message {
72 &self.msg
73 }
74}
75