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