1use serde::{
2 de::{Error, SeqAccess, Visitor},
3 ser::{SerializeSeq, SerializeStruct},
4 Deserialize, Deserializer, Serialize, Serializer,
5};
6use std::{borrow::Cow, num::NonZeroU32};
7use zbus_names::{BusName, ErrorName, InterfaceName, MemberName, UniqueName};
8use zvariant::{ObjectPath, Signature, Type, Value};
9
10use crate::message::{FieldCode, Header, Message};
11
12#[derive(Debug, Default, Clone, Type)]
16#[zvariant(signature = "a(yv)")]
17pub(crate) struct Fields<'f> {
18 pub path: Option<ObjectPath<'f>>,
19 pub interface: Option<InterfaceName<'f>>,
20 pub member: Option<MemberName<'f>>,
21 pub error_name: Option<ErrorName<'f>>,
22 pub reply_serial: Option<NonZeroU32>,
23 pub destination: Option<BusName<'f>>,
24 pub sender: Option<UniqueName<'f>>,
25 pub signature: Cow<'f, Signature>,
26 pub unix_fds: Option<u32>,
27}
28
29impl Fields<'_> {
30 pub fn new() -> Self {
32 Self::default()
33 }
34}
35
36impl Serialize for Fields<'_> {
37 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38 where
39 S: Serializer,
40 {
41 let mut seq = serializer.serialize_seq(None)?;
42 if let Some(path) = &self.path {
43 seq.serialize_element(&(FieldCode::Path, Value::from(path)))?;
44 }
45 if let Some(interface) = &self.interface {
46 seq.serialize_element(&(FieldCode::Interface, Value::from(interface.as_str())))?;
47 }
48 if let Some(member) = &self.member {
49 seq.serialize_element(&(FieldCode::Member, Value::from(member.as_str())))?;
50 }
51 if let Some(error_name) = &self.error_name {
52 seq.serialize_element(&(FieldCode::ErrorName, Value::from(error_name.as_str())))?;
53 }
54 if let Some(reply_serial) = self.reply_serial {
55 seq.serialize_element(&(FieldCode::ReplySerial, Value::from(reply_serial.get())))?;
56 }
57 if let Some(destination) = &self.destination {
58 seq.serialize_element(&(FieldCode::Destination, Value::from(destination.as_str())))?;
59 }
60 if let Some(sender) = &self.sender {
61 seq.serialize_element(&(FieldCode::Sender, Value::from(sender.as_str())))?;
62 }
63 if !matches!(&*self.signature, Signature::Unit) {
64 seq.serialize_element(&(FieldCode::Signature, SignatureSerializer(&self.signature)))?;
65 }
66 if let Some(unix_fds) = self.unix_fds {
67 seq.serialize_element(&(FieldCode::UnixFDs, Value::from(unix_fds)))?;
68 }
69 seq.end()
70 }
71}
72
73#[derive(Debug, Type)]
79#[zvariant(signature = "v")]
80struct SignatureSerializer<'a>(&'a Signature);
81
82impl Serialize for SignatureSerializer<'_> {
83 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84 where
85 S: Serializer,
86 {
87 let mut structure = serializer.serialize_struct("Variant", 2)?;
88
89 structure.serialize_field("signature", &Signature::Signature)?;
90
91 let signature_str = self.0.to_string_no_parens();
92 structure.serialize_field("value", &signature_str)?;
93
94 structure.end()
95 }
96}
97
98impl<'de: 'f, 'f> Deserialize<'de> for Fields<'f> {
99 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
100 where
101 D: Deserializer<'de>,
102 {
103 deserializer.deserialize_seq(FieldsVisitor)
104 }
105}
106
107struct FieldsVisitor;
108
109impl<'de> Visitor<'de> for FieldsVisitor {
110 type Value = Fields<'de>;
111
112 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 formatter.write_str("D-Bus message header fields")
114 }
115
116 fn visit_seq<V>(self, mut visitor: V) -> Result<Fields<'de>, V::Error>
117 where
118 V: SeqAccess<'de>,
119 {
120 let mut fields = Fields::new();
121 while let Some((code, value)) = visitor.next_element::<(FieldCode, Value<'de>)>()? {
122 match code {
123 FieldCode::Path => {
124 fields.path = Some(ObjectPath::try_from(value).map_err(V::Error::custom)?)
125 }
126 FieldCode::Interface => {
127 fields.interface =
128 Some(InterfaceName::try_from(value).map_err(V::Error::custom)?)
129 }
130 FieldCode::Member => {
131 fields.member = Some(MemberName::try_from(value).map_err(V::Error::custom)?)
132 }
133 FieldCode::ErrorName => {
134 fields.error_name = Some(ErrorName::try_from(value).map_err(V::Error::custom)?)
135 }
136 FieldCode::ReplySerial => {
137 let value = u32::try_from(value)
138 .map_err(V::Error::custom)
139 .and_then(|v| v.try_into().map_err(V::Error::custom))?;
140 fields.reply_serial = Some(value)
141 }
142 FieldCode::Destination => {
143 fields.destination = Some(BusName::try_from(value).map_err(V::Error::custom)?)
144 }
145 FieldCode::Sender => {
146 fields.sender = Some(UniqueName::try_from(value).map_err(V::Error::custom)?)
147 }
148 FieldCode::Signature => {
149 fields.signature =
150 Cow::Owned(Signature::try_from(value).map_err(V::Error::custom)?)
151 }
152 FieldCode::UnixFDs => {
153 fields.unix_fds = Some(u32::try_from(value).map_err(V::Error::custom)?)
154 }
155 }
156 }
157
158 Ok(fields)
159 }
160}
161
162#[derive(Debug, Default, Clone, Copy)]
166pub(crate) struct FieldPos {
167 start: u32,
168 end: u32,
169}
170
171impl FieldPos {
172 pub fn new_not_present() -> Self {
173 Self { start: 1, end: 0 }
174 }
175
176 pub fn build(msg_buf: &[u8], field_buf: &str) -> Option<Self> {
177 let buf_start = msg_buf.as_ptr() as usize;
178 let field_start = field_buf.as_ptr() as usize;
179 let offset = field_start.checked_sub(buf_start)?;
180 if offset <= msg_buf.len() && offset + field_buf.len() <= msg_buf.len() {
181 Some(Self {
182 start: offset.try_into().ok()?,
183 end: (offset + field_buf.len()).try_into().ok()?,
184 })
185 } else {
186 None
187 }
188 }
189
190 pub fn new<T>(msg_buf: &[u8], field: Option<&T>) -> Self
191 where
192 T: std::ops::Deref<Target = str>,
193 {
194 field
195 .and_then(|f| Self::build(msg_buf, f.deref()))
196 .unwrap_or_else(Self::new_not_present)
197 }
198
199 pub fn read<'m, T>(&self, msg_buf: &'m [u8]) -> Option<T>
204 where
205 T: TryFrom<&'m str>,
206 T::Error: std::fmt::Debug,
207 {
208 match self {
209 Self {
210 start: 0..=1,
211 end: 0,
212 } => None,
213 Self { start, end } => {
214 let s = std::str::from_utf8(&msg_buf[(*start as usize)..(*end as usize)])
215 .expect("Invalid utf8 when reconstructing string");
216 T::try_from(s)
218 .map(Some)
219 .expect("Invalid field reconstruction")
220 }
221 }
222 }
223}
224
225#[derive(Debug, Default, Clone)]
227pub(crate) struct QuickFields {
228 path: FieldPos,
229 interface: FieldPos,
230 member: FieldPos,
231 error_name: FieldPos,
232 reply_serial: Option<NonZeroU32>,
233 destination: FieldPos,
234 sender: FieldPos,
235 signature: Signature,
236 unix_fds: Option<u32>,
237}
238
239impl QuickFields {
240 pub fn new(buf: &[u8], header: &Header<'_>) -> Self {
241 Self {
242 path: FieldPos::new(buf, header.path()),
243 interface: FieldPos::new(buf, header.interface()),
244 member: FieldPos::new(buf, header.member()),
245 error_name: FieldPos::new(buf, header.error_name()),
246 reply_serial: header.reply_serial(),
247 destination: FieldPos::new(buf, header.destination()),
248 sender: FieldPos::new(buf, header.sender()),
249 signature: header.signature().clone(),
250 unix_fds: header.unix_fds(),
251 }
252 }
253
254 pub fn path<'m>(&self, msg: &'m Message) -> Option<ObjectPath<'m>> {
255 self.path.read(msg.data())
256 }
257
258 pub fn interface<'m>(&self, msg: &'m Message) -> Option<InterfaceName<'m>> {
259 self.interface.read(msg.data())
260 }
261
262 pub fn member<'m>(&self, msg: &'m Message) -> Option<MemberName<'m>> {
263 self.member.read(msg.data())
264 }
265
266 pub fn error_name<'m>(&self, msg: &'m Message) -> Option<ErrorName<'m>> {
267 self.error_name.read(msg.data())
268 }
269
270 pub fn reply_serial(&self) -> Option<NonZeroU32> {
271 self.reply_serial
272 }
273
274 pub fn destination<'m>(&self, msg: &'m Message) -> Option<BusName<'m>> {
275 self.destination.read(msg.data())
276 }
277
278 pub fn sender<'m>(&self, msg: &'m Message) -> Option<UniqueName<'m>> {
279 self.sender.read(msg.data())
280 }
281
282 pub fn signature(&self) -> &Signature {
283 &self.signature
284 }
285
286 pub fn unix_fds(&self) -> Option<u32> {
287 self.unix_fds
288 }
289}