| 1 | use zvariant::{ |
| 2 | serialized::{self, Data}, |
| 3 | Signature, Type, |
| 4 | }; |
| 5 | |
| 6 | use 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)] |
| 12 | pub struct Body { |
| 13 | data: Data<'static, 'static>, |
| 14 | msg: Message, |
| 15 | } |
| 16 | |
| 17 | impl 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 | |