1use std::num::NonZeroU32;
2
3use serde::{
4 de::{Deserialize, Deserializer, Error},
5 ser::{Serialize, Serializer},
6};
7use serde_repr::{Deserialize_repr, Serialize_repr};
8
9use static_assertions::assert_impl_all;
10use zbus_names::{BusName, ErrorName, InterfaceName, MemberName, UniqueName};
11use zvariant::{ObjectPath, Signature, Type, Value};
12
13#[repr(u8)]
23#[derive(Copy, Clone, Debug, Deserialize_repr, PartialEq, Eq, Serialize_repr, Type)]
24pub(crate) enum FieldCode {
25 Path = 1,
27 Interface = 2,
29 Member = 3,
31 ErrorName = 4,
33 ReplySerial = 5,
35 Destination = 6,
37 Sender = 7,
39 Signature = 8,
41 UnixFDs = 9,
43}
44
45assert_impl_all!(FieldCode: Send, Sync, Unpin);
46
47impl<'f> Field<'f> {
48 pub fn code(&self) -> FieldCode {
50 match self {
51 Field::Path(_) => FieldCode::Path,
52 Field::Interface(_) => FieldCode::Interface,
53 Field::Member(_) => FieldCode::Member,
54 Field::ErrorName(_) => FieldCode::ErrorName,
55 Field::ReplySerial(_) => FieldCode::ReplySerial,
56 Field::Destination(_) => FieldCode::Destination,
57 Field::Sender(_) => FieldCode::Sender,
58 Field::Signature(_) => FieldCode::Signature,
59 Field::UnixFDs(_) => FieldCode::UnixFDs,
60 }
61 }
62}
63
64#[derive(Clone, Debug, PartialEq, Eq)]
76pub(crate) enum Field<'f> {
77 Path(ObjectPath<'f>),
79 Interface(InterfaceName<'f>),
81 Member(MemberName<'f>),
83 ErrorName(ErrorName<'f>),
85 ReplySerial(NonZeroU32),
87 Destination(BusName<'f>),
89 Sender(UniqueName<'f>),
91 Signature(Signature<'f>),
93 UnixFDs(u32),
95}
96
97assert_impl_all!(Field<'_>: Send, Sync, Unpin);
98
99impl<'f> Type for Field<'f> {
100 fn signature() -> Signature<'static> {
101 Signature::from_static_str_unchecked("(yv)")
102 }
103}
104
105impl<'f> Serialize for Field<'f> {
106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107 where
108 S: Serializer,
109 {
110 let tuple: (FieldCode, Value<'_>) = match self {
111 Field::Path(value) => (FieldCode::Path, value.as_ref().into()),
112 Field::Interface(value) => (FieldCode::Interface, value.as_str().into()),
113 Field::Member(value) => (FieldCode::Member, value.as_str().into()),
114 Field::ErrorName(value) => (FieldCode::ErrorName, value.as_str().into()),
115 Field::ReplySerial(value) => (FieldCode::ReplySerial, value.get().into()),
116 Field::Destination(value) => (FieldCode::Destination, value.as_str().into()),
117 Field::Sender(value) => (FieldCode::Sender, value.as_str().into()),
118 Field::Signature(value) => (FieldCode::Signature, value.as_ref().into()),
119 Field::UnixFDs(value) => (FieldCode::UnixFDs, (*value).into()),
120 };
121
122 tuple.serialize(serializer)
123 }
124}
125
126impl<'de: 'f, 'f> Deserialize<'de> for Field<'f> {
127 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128 where
129 D: Deserializer<'de>,
130 {
131 let (code, value) = <(FieldCode, Value<'_>)>::deserialize(deserializer)?;
132 Ok(match code {
133 FieldCode::Path => Field::Path(ObjectPath::try_from(value).map_err(D::Error::custom)?),
134 FieldCode::Interface => {
135 Field::Interface(InterfaceName::try_from(value).map_err(D::Error::custom)?)
136 }
137 FieldCode::Member => {
138 Field::Member(MemberName::try_from(value).map_err(D::Error::custom)?)
139 }
140 FieldCode::ErrorName => Field::ErrorName(
141 ErrorName::try_from(value)
142 .map(Into::into)
143 .map_err(D::Error::custom)?,
144 ),
145 FieldCode::ReplySerial => {
146 let value = u32::try_from(value)
147 .map_err(D::Error::custom)
148 .and_then(|v| v.try_into().map_err(D::Error::custom))?;
149 Field::ReplySerial(value)
150 }
151 FieldCode::Destination => Field::Destination(
152 BusName::try_from(value)
153 .map(Into::into)
154 .map_err(D::Error::custom)?,
155 ),
156 FieldCode::Sender => Field::Sender(
157 UniqueName::try_from(value)
158 .map(Into::into)
159 .map_err(D::Error::custom)?,
160 ),
161 FieldCode::Signature => {
162 Field::Signature(Signature::try_from(value).map_err(D::Error::custom)?)
163 }
164 FieldCode::UnixFDs => Field::UnixFDs(u32::try_from(value).map_err(D::Error::custom)?),
165 })
166 }
167}