sqlx_build_trust_core/ext/
ustr.rs

1use std::borrow::Borrow;
2use std::fmt::{self, Debug, Display, Formatter};
3use std::hash::{Hash, Hasher};
4use std::ops::Deref;
5use std::sync::Arc;
6
7// U meaning micro
8// a micro-string is either a reference-counted string or a static string
9// this guarantees these are cheap to clone everywhere
10#[derive(Clone, Eq)]
11pub enum UStr {
12    Static(&'static str),
13    Shared(Arc<str>),
14}
15
16impl UStr {
17    pub fn new(s: &str) -> Self {
18        UStr::Shared(Arc::from(s.to_owned()))
19    }
20}
21
22impl Deref for UStr {
23    type Target = str;
24
25    #[inline]
26    fn deref(&self) -> &str {
27        match self {
28            UStr::Static(s) => s,
29            UStr::Shared(s) => s,
30        }
31    }
32}
33
34impl Hash for UStr {
35    #[inline]
36    fn hash<H: Hasher>(&self, state: &mut H) {
37        // Forward the hash to the string representation of this
38        // A derive(Hash) encodes the enum discriminant
39        (&**self).hash(state);
40    }
41}
42
43impl Borrow<str> for UStr {
44    #[inline]
45    fn borrow(&self) -> &str {
46        &**self
47    }
48}
49
50impl PartialEq<UStr> for UStr {
51    fn eq(&self, other: &UStr) -> bool {
52        (**self).eq(&**other)
53    }
54}
55
56impl From<&'static str> for UStr {
57    #[inline]
58    fn from(s: &'static str) -> Self {
59        UStr::Static(s)
60    }
61}
62
63impl From<String> for UStr {
64    #[inline]
65    fn from(s: String) -> Self {
66        UStr::Shared(s.into())
67    }
68}
69
70impl Debug for UStr {
71    #[inline]
72    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
73        f.pad(self)
74    }
75}
76
77impl Display for UStr {
78    #[inline]
79    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
80        f.pad(self)
81    }
82}
83
84// manual impls because otherwise things get a little screwy with lifetimes
85
86#[cfg(feature = "offline")]
87impl<'de> serde::Deserialize<'de> for UStr {
88    fn deserialize<D>(deserializer: D) -> Result<Self, <D as serde::Deserializer<'de>>::Error>
89    where
90        D: serde::Deserializer<'de>,
91    {
92        Ok(String::deserialize(deserializer)?.into())
93    }
94}
95
96#[cfg(feature = "offline")]
97impl serde::Serialize for UStr {
98    fn serialize<S>(
99        &self,
100        serializer: S,
101    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
102    where
103        S: serde::Serializer,
104    {
105        serializer.serialize_str(&self)
106    }
107}