zvariant/
serialize_value.rs

1use serde::ser::{Serialize, SerializeStruct, Serializer};
2use static_assertions::assert_impl_all;
3
4use crate::{Signature, Type, Value};
5
6/// A wrapper to serialize `T: Type + Serialize` as a value.
7///
8/// When the type of a value is well-known, you may avoid the cost and complexity of wrapping to a
9/// generic [`Value`] and instead use this wrapper.
10///
11/// ```
12/// # use zvariant::{to_bytes, EncodingContext, SerializeValue};
13/// #
14/// # let ctxt = EncodingContext::<byteorder::LE>::new_dbus(0);
15/// let _ = to_bytes(ctxt, &SerializeValue(&[0, 1, 2])).unwrap();
16/// ```
17///
18/// [`Value`]: enum.Value.html
19pub struct SerializeValue<'a, T: Type + Serialize>(pub &'a T);
20
21assert_impl_all!(SerializeValue<'_, i32>: Send, Sync, Unpin);
22
23impl<'a, T: Type + Serialize> Serialize for SerializeValue<'a, T> {
24    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
25    where
26        S: Serializer,
27    {
28        // Serializer implementation needs to ensure padding isn't added for Value.
29        let mut structure = serializer.serialize_struct("zvariant::Value", 2)?;
30
31        let signature = T::signature();
32        structure.serialize_field("zvariant::Value::Signature", &signature)?;
33        structure.serialize_field("zvariant::Value::Value", self.0)?;
34
35        structure.end()
36    }
37}
38
39impl<'a, T: Type + Serialize> Type for SerializeValue<'a, T> {
40    fn signature() -> Signature<'static> {
41        Value::signature()
42    }
43}