1use core::{
2 cmp::Ordering,
3 fmt::{self, Debug, Display, Formatter},
4 hash::{Hash, Hasher},
5 str,
6};
7use serde::{
8 de::{Deserialize, Deserializer},
9 ser::{Serialize, Serializer},
10};
11use static_assertions::assert_impl_all;
12use std::{
13 borrow::Cow,
14 ops::{Bound, RangeBounds},
15 sync::Arc,
16};
17
18use crate::{serialized::Format, signature_parser::SignatureParser, Basic, Error, Result, Type};
19
20#[derive(Debug, Clone)]
26enum Bytes<'b> {
27 Borrowed(&'b [u8]),
28 Static(&'static [u8]),
29 Owned(Arc<[u8]>),
30}
31
32impl<'b> Bytes<'b> {
33 const fn borrowed<'s: 'b>(bytes: &'s [u8]) -> Self {
34 Self::Borrowed(bytes)
35 }
36
37 fn owned(bytes: Vec<u8>) -> Self {
38 Self::Owned(bytes.into())
39 }
40
41 fn as_ref(&self) -> Bytes<'_> {
43 match &self {
44 Bytes::Static(s) => Bytes::Static(s),
45 Bytes::Borrowed(s) => Bytes::Borrowed(s),
46 Bytes::Owned(s) => Bytes::Borrowed(s),
47 }
48 }
49}
50
51impl std::ops::Deref for Bytes<'_> {
52 type Target = [u8];
53
54 fn deref(&self) -> &[u8] {
55 match self {
56 Bytes::Borrowed(borrowed) => borrowed,
57 Bytes::Static(borrowed) => borrowed,
58 Bytes::Owned(owned) => owned,
59 }
60 }
61}
62
63impl Eq for Bytes<'_> {}
64
65impl PartialEq for Bytes<'_> {
66 fn eq(&self, other: &Self) -> bool {
67 **self == **other
68 }
69}
70
71impl Ord for Bytes<'_> {
72 fn cmp(&self, other: &Self) -> Ordering {
73 (**self).cmp(&**other)
74 }
75}
76
77impl PartialOrd for Bytes<'_> {
78 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
79 Some(self.cmp(other))
80 }
81}
82
83impl Hash for Bytes<'_> {
84 fn hash<H: Hasher>(&self, state: &mut H) {
85 (**self).hash(state)
86 }
87}
88
89#[derive(Hash, Clone, PartialOrd, Ord)]
128pub struct Signature<'a> {
129 bytes: Bytes<'a>,
130 pos: usize,
131 end: usize,
132}
133
134assert_impl_all!(Signature<'_>: Send, Sync, Unpin);
135
136impl<'a> Signature<'a> {
137 pub fn as_str(&self) -> &str {
139 unsafe { str::from_utf8_unchecked(self.as_bytes()) }
141 }
142
143 pub fn as_bytes(&self) -> &[u8] {
145 &self.bytes[self.pos..self.end]
146 }
147
148 pub fn as_ref(&self) -> Signature<'_> {
150 Signature {
151 bytes: self.bytes.as_ref(),
152 pos: self.pos,
153 end: self.end,
154 }
155 }
156
157 pub unsafe fn from_bytes_unchecked<'s: 'a>(bytes: &'s [u8]) -> Self {
166 Self {
167 bytes: Bytes::borrowed(bytes),
168 pos: 0,
169 end: bytes.len(),
170 }
171 }
172
173 pub unsafe fn from_static_bytes_unchecked(bytes: &'static [u8]) -> Self {
179 Self {
180 bytes: Bytes::Static(bytes),
181 pos: 0,
182 end: bytes.len(),
183 }
184 }
185
186 pub const fn from_str_unchecked<'s: 'a>(signature: &'s str) -> Self {
188 Self {
189 bytes: Bytes::borrowed(signature.as_bytes()),
190 pos: 0,
191 end: signature.len(),
192 }
193 }
194
195 pub const fn from_static_str_unchecked(signature: &'static str) -> Self {
197 Self {
198 bytes: Bytes::Static(signature.as_bytes()),
199 pos: 0,
200 end: signature.len(),
201 }
202 }
203
204 pub fn from_string_unchecked(signature: String) -> Self {
206 let bytes = signature.into_bytes();
207 let end = bytes.len();
208
209 Self {
210 bytes: Bytes::owned(bytes),
211 pos: 0,
212 end,
213 }
214 }
215
216 pub fn from_static_str(signature: &'static str) -> Result<Self> {
222 let bytes = signature.as_bytes();
223 SignatureParser::validate(bytes)?;
224
225 Ok(Self {
226 bytes: Bytes::Static(bytes),
227 pos: 0,
228 end: signature.len(),
229 })
230 }
231
232 pub fn from_static_bytes(bytes: &'static [u8]) -> Result<Self> {
238 SignatureParser::validate(bytes)?;
239
240 Ok(Self {
241 bytes: Bytes::Static(bytes),
242 pos: 0,
243 end: bytes.len(),
244 })
245 }
246
247 pub fn len(&self) -> usize {
249 self.end - self.pos
250 }
251
252 pub fn is_empty(&self) -> bool {
254 self.as_bytes().is_empty()
255 }
256
257 pub fn to_owned(&self) -> Signature<'static> {
259 match &self.bytes {
260 Bytes::Borrowed(_) => {
261 let bytes = Bytes::owned(self.as_bytes().to_vec());
262 let pos = 0;
263 let end = bytes.len();
264
265 Signature { bytes, pos, end }
266 }
267 Bytes::Static(b) => Signature {
268 bytes: Bytes::Static(b),
269 pos: self.pos,
270 end: self.end,
271 },
272 Bytes::Owned(owned) => Signature {
273 bytes: Bytes::Owned(owned.clone()),
274 pos: self.pos,
275 end: self.end,
276 },
277 }
278 }
279
280 pub fn into_owned(self) -> Signature<'static> {
282 self.to_owned()
283 }
284
285 #[must_use]
291 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
292 let len = self.len();
293
294 let pos = match range.start_bound() {
295 Bound::Included(&n) => n,
296 Bound::Excluded(&n) => n + 1,
297 Bound::Unbounded => 0,
298 };
299
300 let end = match range.end_bound() {
301 Bound::Included(&n) => n + 1,
302 Bound::Excluded(&n) => n,
303 Bound::Unbounded => len,
304 };
305
306 assert!(
307 pos <= end,
308 "range start must not be greater than end: {:?} > {:?}",
309 pos,
310 end,
311 );
312 assert!(end <= len, "range end out of bounds: {:?} > {:?}", end, len,);
313
314 if end == pos {
315 return Self::from_str_unchecked("");
316 }
317
318 let mut clone = self.clone();
319 clone.pos += pos;
320 clone.end = self.pos + end;
321
322 clone
323 }
324
325 pub fn n_complete_types(&self) -> Result<usize> {
331 let mut count = 0;
332 for s in unsafe { SignatureParser::from_bytes_unchecked(self.as_bytes())? } {
334 s?;
335 count += 1;
336 }
337 Ok(count)
338 }
339}
340
341impl<'a> Debug for Signature<'a> {
342 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343 f.debug_tuple("Signature").field(&self.as_str()).finish()
344 }
345}
346
347impl<'a> Basic for Signature<'a> {
348 const SIGNATURE_CHAR: char = 'g';
349 const SIGNATURE_STR: &'static str = "g";
350
351 fn alignment(format: Format) -> usize {
352 match format {
353 Format::DBus => 1,
354 #[cfg(feature = "gvariant")]
355 Format::GVariant => 1,
356 }
357 }
358}
359
360impl<'a> Type for Signature<'a> {
361 fn signature() -> Signature<'static> {
362 Signature::from_static_str_unchecked(Self::SIGNATURE_STR)
363 }
364}
365
366impl<'a> From<&Signature<'a>> for Signature<'a> {
367 fn from(signature: &Signature<'a>) -> Signature<'a> {
368 signature.clone()
369 }
370}
371
372impl<'a> TryFrom<&'a [u8]> for Signature<'a> {
373 type Error = Error;
374
375 fn try_from(value: &'a [u8]) -> Result<Self> {
376 SignatureParser::validate(value)?;
377
378 unsafe { Ok(Self::from_bytes_unchecked(value)) }
380 }
381}
382
383impl<'a> TryFrom<&'a str> for Signature<'a> {
385 type Error = Error;
386
387 fn try_from(value: &'a str) -> Result<Self> {
388 Self::try_from(value.as_bytes())
389 }
390}
391
392impl<'a> TryFrom<Cow<'a, str>> for Signature<'a> {
394 type Error = Error;
395
396 fn try_from(value: Cow<'a, str>) -> Result<Self> {
397 match value {
398 Cow::Borrowed(v) => Self::try_from(v),
399 Cow::Owned(v) => Self::try_from(v),
400 }
401 }
402}
403
404impl<'a> TryFrom<String> for Signature<'a> {
405 type Error = Error;
406
407 fn try_from(value: String) -> Result<Self> {
408 SignatureParser::validate(value.as_bytes())?;
409
410 Ok(Self::from_string_unchecked(value))
411 }
412}
413
414impl<'a> From<Signature<'a>> for String {
415 fn from(value: Signature<'a>) -> String {
416 String::from(value.as_str())
417 }
418}
419
420impl<'a> From<&Signature<'a>> for String {
421 fn from(value: &Signature<'a>) -> String {
422 String::from(value.as_str())
423 }
424}
425
426impl<'a> std::ops::Deref for Signature<'a> {
427 type Target = str;
428
429 fn deref(&self) -> &Self::Target {
430 self.as_str()
431 }
432}
433
434fn has_balanced_parentheses(signature_str: &str) -> bool {
436 signature_str.chars().fold(0, |count, ch| match ch {
437 '(' => count + 1,
438 ')' if count != 0 => count - 1,
439 _ => count,
440 }) == 0
441}
442
443fn without_outer_parentheses<'a, 'b>(sig: &'a Signature<'b>) -> &'a str
446where
447 'b: 'a,
448{
449 let sig_str = sig.as_str();
450
451 if let Some(subslice) = sig_str.strip_prefix('(').and_then(|s| s.strip_suffix(')')) {
452 if has_balanced_parentheses(subslice) {
453 return subslice;
454 }
455 }
456 sig_str
457}
458
459impl<'a, 'b> PartialEq<Signature<'a>> for Signature<'b> {
461 fn eq(&self, other: &Signature<'_>) -> bool {
462 without_outer_parentheses(self) == without_outer_parentheses(other)
463 }
464}
465
466impl<'a> PartialEq<str> for Signature<'a> {
467 fn eq(&self, other: &str) -> bool {
468 self.as_bytes() == other.as_bytes()
469 }
470}
471
472impl<'a> PartialEq<&str> for Signature<'a> {
473 fn eq(&self, other: &&str) -> bool {
474 self.as_bytes() == other.as_bytes()
475 }
476}
477
478impl Eq for Signature<'_> {}
481
482impl<'a> Display for Signature<'a> {
483 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
484 std::fmt::Display::fmt(&self.as_str(), f)
485 }
486}
487
488impl<'a> Serialize for Signature<'a> {
489 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
490 where
491 S: Serializer,
492 {
493 serializer.serialize_str(self.as_str())
494 }
495}
496
497impl<'de: 'a, 'a> Deserialize<'de> for Signature<'a> {
498 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
499 where
500 D: Deserializer<'de>,
501 {
502 let val = <std::borrow::Cow<'a, str>>::deserialize(deserializer)?;
503
504 Self::try_from(val).map_err(serde::de::Error::custom)
505 }
506}
507
508#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, Type)]
510pub struct OwnedSignature(Signature<'static>);
511
512assert_impl_all!(OwnedSignature: Send, Sync, Unpin);
513
514impl OwnedSignature {
515 pub fn into_inner(self) -> Signature<'static> {
516 self.0
517 }
518}
519
520impl Basic for OwnedSignature {
521 const SIGNATURE_CHAR: char = Signature::SIGNATURE_CHAR;
522 const SIGNATURE_STR: &'static str = Signature::SIGNATURE_STR;
523
524 fn alignment(format: Format) -> usize {
525 Signature::alignment(format)
526 }
527}
528
529impl std::ops::Deref for OwnedSignature {
530 type Target = Signature<'static>;
531
532 fn deref(&self) -> &Self::Target {
533 &self.0
534 }
535}
536
537impl std::convert::From<OwnedSignature> for Signature<'static> {
538 fn from(o: OwnedSignature) -> Self {
539 o.into_inner()
540 }
541}
542
543impl<'a> std::convert::From<Signature<'a>> for OwnedSignature {
544 fn from(o: Signature<'a>) -> Self {
545 OwnedSignature(o.into_owned())
546 }
547}
548
549impl std::convert::From<OwnedSignature> for crate::Value<'static> {
550 fn from(o: OwnedSignature) -> Self {
551 o.into_inner().into()
552 }
553}
554
555impl TryFrom<String> for OwnedSignature {
556 type Error = Error;
557
558 fn try_from(value: String) -> Result<Self> {
559 Ok(Self(Signature::try_from(value)?))
560 }
561}
562
563impl<'de> Deserialize<'de> for OwnedSignature {
564 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
565 where
566 D: Deserializer<'de>,
567 {
568 let val = String::deserialize(deserializer)?;
569
570 OwnedSignature::try_from(val).map_err(serde::de::Error::custom)
571 }
572}
573
574impl std::fmt::Display for OwnedSignature {
575 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
576 std::fmt::Display::fmt(&self.as_str(), f)
577 }
578}
579
580#[cfg(test)]
581mod tests {
582 use super::{Bytes, Signature};
583 use std::sync::Arc;
584
585 #[test]
586 fn bytes_equality() {
587 let borrowed1 = Bytes::Borrowed(b"foo");
588 let borrowed2 = Bytes::Borrowed(b"foo");
589 let static1 = Bytes::Static(b"foo");
590 let static2 = Bytes::Static(b"foo");
591 let owned1 = Bytes::Owned(Arc::new(*b"foo"));
592 let owned2 = Bytes::Owned(Arc::new(*b"foo"));
593
594 assert_eq!(borrowed1, borrowed2);
595 assert_eq!(static1, static2);
596 assert_eq!(owned1, owned2);
597
598 assert_eq!(borrowed1, static1);
599 assert_eq!(static1, borrowed1);
600
601 assert_eq!(static1, owned1);
602 assert_eq!(owned1, static1);
603
604 assert_eq!(borrowed1, owned1);
605 assert_eq!(owned1, borrowed1);
606 }
607
608 #[test]
609 fn signature_slicing() {
610 let sig = Signature::from_str_unchecked("(asta{sv})");
611 assert_eq!(sig, "(asta{sv})");
612
613 let slice = sig.slice(1..);
614 assert_eq!(slice.len(), sig.len() - 1);
615 assert_eq!(slice, &sig[1..]);
616 assert_eq!(slice.as_bytes()[1], b's');
617 assert_eq!(slice.as_bytes()[2], b't');
618
619 let slice = slice.slice(2..3);
620 assert_eq!(slice.len(), 1);
621 assert_eq!(slice, "t");
622 assert_eq!(slice.slice(1..), "");
623 }
624
625 #[test]
626 fn signature_equality() {
627 let sig_a = Signature::from_str_unchecked("(asta{sv})");
628 let sig_b = Signature::from_str_unchecked("asta{sv}");
629 assert_eq!(sig_a, sig_b);
630
631 let sig_a = Signature::from_str_unchecked("((so)ii(uu))");
632 let sig_b = Signature::from_str_unchecked("(so)ii(uu)");
633 assert_eq!(sig_a, sig_b);
634
635 let sig_a = Signature::from_str_unchecked("(so)i");
636 let sig_b = Signature::from_str_unchecked("(so)u");
637 assert_ne!(sig_a, sig_b);
638 }
639}