1use std::convert::TryFrom;
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 enum MessageFieldCode {
25 Invalid = 0,
27 Path = 1,
29 Interface = 2,
31 Member = 3,
33 ErrorName = 4,
35 ReplySerial = 5,
37 Destination = 6,
39 Sender = 7,
41 Signature = 8,
43 UnixFDs = 9,
45}
46
47assert_impl_all!(MessageFieldCode: Send, Sync, Unpin);
48
49impl From<u8> for MessageFieldCode {
50 fn from(val: u8) -> MessageFieldCode {
51 match val {
52 1 => MessageFieldCode::Path,
53 2 => MessageFieldCode::Interface,
54 3 => MessageFieldCode::Member,
55 4 => MessageFieldCode::ErrorName,
56 5 => MessageFieldCode::ReplySerial,
57 6 => MessageFieldCode::Destination,
58 7 => MessageFieldCode::Sender,
59 8 => MessageFieldCode::Signature,
60 9 => MessageFieldCode::UnixFDs,
61 _ => MessageFieldCode::Invalid,
62 }
63 }
64}
65
66impl<'f> MessageField<'f> {
67 pub fn code(&self) -> MessageFieldCode {
69 match self {
70 MessageField::Path(_) => MessageFieldCode::Path,
71 MessageField::Interface(_) => MessageFieldCode::Interface,
72 MessageField::Member(_) => MessageFieldCode::Member,
73 MessageField::ErrorName(_) => MessageFieldCode::ErrorName,
74 MessageField::ReplySerial(_) => MessageFieldCode::ReplySerial,
75 MessageField::Destination(_) => MessageFieldCode::Destination,
76 MessageField::Sender(_) => MessageFieldCode::Sender,
77 MessageField::Signature(_) => MessageFieldCode::Signature,
78 MessageField::UnixFDs(_) => MessageFieldCode::UnixFDs,
79 MessageField::Invalid => MessageFieldCode::Invalid,
80 }
81 }
82}
83
84#[derive(Clone, Debug, PartialEq, Eq)]
96pub enum MessageField<'f> {
97 Invalid,
99 Path(ObjectPath<'f>),
101 Interface(InterfaceName<'f>),
103 Member(MemberName<'f>),
105 ErrorName(ErrorName<'f>),
107 ReplySerial(u32),
109 Destination(BusName<'f>),
111 Sender(UniqueName<'f>),
113 Signature(Signature<'f>),
115 UnixFDs(u32),
117}
118
119assert_impl_all!(MessageField<'_>: Send, Sync, Unpin);
120
121impl<'f> Type for MessageField<'f> {
122 fn signature() -> Signature<'static> {
123 Signature::from_static_str_unchecked("(yv)")
124 }
125}
126
127impl<'f> Serialize for MessageField<'f> {
128 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
129 where
130 S: Serializer,
131 {
132 let tuple: (MessageFieldCode, Value<'_>) = match self {
133 MessageField::Path(value) => (MessageFieldCode::Path, value.clone().into()),
134 MessageField::Interface(value) => (MessageFieldCode::Interface, value.as_str().into()),
135 MessageField::Member(value) => (MessageFieldCode::Member, value.as_str().into()),
136 MessageField::ErrorName(value) => (MessageFieldCode::ErrorName, value.as_str().into()),
137 MessageField::ReplySerial(value) => (MessageFieldCode::ReplySerial, (*value).into()),
138 MessageField::Destination(value) => {
139 (MessageFieldCode::Destination, value.as_str().into())
140 }
141 MessageField::Sender(value) => (MessageFieldCode::Sender, value.as_str().into()),
142 MessageField::Signature(value) => (MessageFieldCode::Signature, value.clone().into()),
143 MessageField::UnixFDs(value) => (MessageFieldCode::UnixFDs, (*value).into()),
144 MessageField::Invalid => panic!("Attempt to serialize invalid MessageField"),
146 };
147
148 tuple.serialize(serializer)
149 }
150}
151
152impl<'de: 'f, 'f> Deserialize<'de> for MessageField<'f> {
153 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
154 where
155 D: Deserializer<'de>,
156 {
157 let (code, value) = <(MessageFieldCode, Value<'_>)>::deserialize(deserializer)?;
158 Ok(match code {
159 MessageFieldCode::Path => {
160 MessageField::Path(ObjectPath::try_from(value).map_err(D::Error::custom)?)
161 }
162 MessageFieldCode::Interface => {
163 MessageField::Interface(InterfaceName::try_from(value).map_err(D::Error::custom)?)
164 }
165 MessageFieldCode::Member => {
166 MessageField::Member(MemberName::try_from(value).map_err(D::Error::custom)?)
167 }
168 MessageFieldCode::ErrorName => MessageField::ErrorName(
169 ErrorName::try_from(value)
170 .map(Into::into)
171 .map_err(D::Error::custom)?,
172 ),
173 MessageFieldCode::ReplySerial => {
174 MessageField::ReplySerial(u32::try_from(value).map_err(D::Error::custom)?)
175 }
176 MessageFieldCode::Destination => MessageField::Destination(
177 BusName::try_from(value)
178 .map(Into::into)
179 .map_err(D::Error::custom)?,
180 ),
181 MessageFieldCode::Sender => MessageField::Sender(
182 UniqueName::try_from(value)
183 .map(Into::into)
184 .map_err(D::Error::custom)?,
185 ),
186 MessageFieldCode::Signature => {
187 MessageField::Signature(Signature::try_from(value).map_err(D::Error::custom)?)
188 }
189 MessageFieldCode::UnixFDs => {
190 MessageField::UnixFDs(u32::try_from(value).map_err(D::Error::custom)?)
191 }
192 MessageFieldCode::Invalid => {
193 return Err(Error::invalid_value(
194 serde::de::Unexpected::Unsigned(code as u64),
195 &"A valid D-Bus message field code",
196 ));
197 }
198 })
199 }
200}