tokio_dbus/body_buf/store_variant.rs
1use crate::ty;
2use crate::{BodyBuf, Signature, Storable};
3
4use super::{StoreArray, StoreStruct};
5
6/// Write the contents of a variant.
7///
8/// The signature of the contained value is written when this is constructed,
9/// after which exactly one value matching that signature must be stored.
10///
11/// Unlike the other writers in this crate a variant is written against a
12/// signature which is provided at runtime. This is what makes it possible to
13/// write recursive types, such as the `(ia{sv}av)` layout of a
14/// `com.canonical.dbusmenu` menu.
15///
16/// See [`BodyBuf::store_variant`].
17///
18/// [`BodyBuf::store_variant`]: crate::BodyBuf::store_variant
19#[must_use = "Writers must be used to store the contents of the variant"]
20pub struct StoreVariant<'a> {
21 buf: &'a mut BodyBuf,
22}
23
24impl<'a> StoreVariant<'a> {
25 pub(crate) fn new(buf: &'a mut BodyBuf, signature: &Signature) -> Self {
26 // NB: The signature of the contained value is written verbatim and is
27 // not part of the signature of the surrounding buffer.
28 buf.write_only(signature);
29 Self { buf }
30 }
31
32 /// Store a value inside of the variant.
33 ///
34 /// Note that a [`Variant`] must *not* be stored this way, since it writes
35 /// its own signature and would end up writing it twice. Store it directly
36 /// instead, with [`BodyBuf::store`] or the `store` of the surrounding
37 /// container.
38 ///
39 /// [`Variant`]: crate::Variant
40 /// [`BodyBuf::store`]: crate::BodyBuf::store
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use tokio_dbus::{BodyBuf, Signature, Variant};
46 ///
47 /// let mut buf = BodyBuf::new();
48 /// buf.store_variant(Signature::STRING)?.store("Hello World!");
49 ///
50 /// assert_eq!(buf.signature(), Signature::VARIANT);
51 ///
52 /// let mut buf = buf.as_body();
53 /// assert_eq!(buf.read_variant()?, Variant::String("Hello World!"));
54 /// # Ok::<_, tokio_dbus::Error>(())
55 /// ```
56 #[inline]
57 pub fn store<T>(self, value: T)
58 where
59 T: Storable,
60 {
61 value.store_to(self.buf);
62 }
63
64 /// Store an array inside of the variant.
65 ///
66 /// # Examples
67 ///
68 /// ```
69 /// use tokio_dbus::{ty, BodyBuf, Signature};
70 ///
71 /// let mut buf = BodyBuf::new();
72 ///
73 /// let mut array = buf.store_variant(Signature::new("as")?)?.store_array::<ty::Str>();
74 /// array.store("Hello");
75 /// array.store("World");
76 /// array.finish();
77 ///
78 /// assert_eq!(buf.signature(), Signature::VARIANT);
79 ///
80 /// let mut buf = buf.as_body();
81 /// assert_eq!(buf.skip_variant()?, Signature::new("as")?);
82 /// # Ok::<_, tokio_dbus::Error>(())
83 /// ```
84 #[inline]
85 pub fn store_array<E>(self) -> StoreArray<'a, E>
86 where
87 E: ty::Aligned,
88 {
89 StoreArray::new(self.buf)
90 }
91
92 /// Store a struct inside of the variant.
93 ///
94 /// # Examples
95 ///
96 /// ```
97 /// use tokio_dbus::{ty, BodyBuf, Signature};
98 ///
99 /// let mut buf = BodyBuf::new();
100 ///
101 /// buf.store_variant(Signature::new("(us)")?)?
102 /// .store_struct::<(u32, ty::Str)>()
103 /// .store(42u32)
104 /// .store("Hello World!")
105 /// .finish();
106 ///
107 /// assert_eq!(buf.signature(), Signature::VARIANT);
108 ///
109 /// let mut buf = buf.as_body();
110 /// assert_eq!(buf.skip_variant()?, Signature::new("(us)")?);
111 /// # Ok::<_, tokio_dbus::Error>(())
112 /// ```
113 #[inline]
114 pub fn store_struct<F>(self) -> StoreStruct<'a, F>
115 where
116 F: ty::Fields,
117 {
118 StoreStruct::new(self.buf)
119 }
120}