uv_small_str/
lib.rs

1use std::borrow::Cow;
2use std::cmp::PartialEq;
3use std::ops::Deref;
4
5/// An optimized type for immutable identifiers. Represented as an [`arcstr::ArcStr`] internally.
6#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct SmallString(arcstr::ArcStr);
8
9impl From<arcstr::ArcStr> for SmallString {
10    #[inline]
11    fn from(s: arcstr::ArcStr) -> Self {
12        Self(s)
13    }
14}
15
16impl From<&str> for SmallString {
17    #[inline]
18    fn from(s: &str) -> Self {
19        Self(s.into())
20    }
21}
22
23impl From<String> for SmallString {
24    #[inline]
25    fn from(s: String) -> Self {
26        Self(s.into())
27    }
28}
29
30impl From<Cow<'_, str>> for SmallString {
31    fn from(s: Cow<'_, str>) -> Self {
32        match s {
33            Cow::Borrowed(s) => Self::from(s),
34            Cow::Owned(s) => Self::from(s),
35        }
36    }
37}
38
39impl AsRef<str> for SmallString {
40    #[inline]
41    fn as_ref(&self) -> &str {
42        &self.0
43    }
44}
45
46impl core::borrow::Borrow<str> for SmallString {
47    #[inline]
48    fn borrow(&self) -> &str {
49        self
50    }
51}
52
53impl Deref for SmallString {
54    type Target = str;
55
56    #[inline]
57    fn deref(&self) -> &Self::Target {
58        &self.0
59    }
60}
61
62impl core::fmt::Debug for SmallString {
63    #[inline]
64    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65        core::fmt::Debug::fmt(&self.0, f)
66    }
67}
68
69impl core::fmt::Display for SmallString {
70    #[inline]
71    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72        core::fmt::Display::fmt(&self.0, f)
73    }
74}
75
76/// A [`serde::Serialize`] implementation for [`SmallString`].
77impl serde::Serialize for SmallString {
78    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
79    where
80        S: serde::Serializer,
81    {
82        self.0.serialize(serializer)
83    }
84}
85
86impl<'de> serde::Deserialize<'de> for SmallString {
87    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
88        struct Visitor;
89
90        impl serde::de::Visitor<'_> for Visitor {
91            type Value = SmallString;
92
93            fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
94                f.write_str("a string")
95            }
96
97            fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
98                Ok(v.into())
99            }
100        }
101
102        deserializer.deserialize_str(Visitor)
103    }
104}
105
106/// An [`rkyv`] implementation for [`SmallString`].
107impl rkyv::Archive for SmallString {
108    type Archived = rkyv::string::ArchivedString;
109    type Resolver = rkyv::string::StringResolver;
110
111    #[inline]
112    fn resolve(&self, resolver: Self::Resolver, out: rkyv::Place<Self::Archived>) {
113        rkyv::string::ArchivedString::resolve_from_str(&self.0, resolver, out);
114    }
115}
116
117impl<S> rkyv::Serialize<S> for SmallString
118where
119    S: rkyv::rancor::Fallible + rkyv::ser::Allocator + rkyv::ser::Writer + ?Sized,
120    S::Error: rkyv::rancor::Source,
121{
122    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
123        rkyv::string::ArchivedString::serialize_from_str(&self.0, serializer)
124    }
125}
126
127impl<D: rkyv::rancor::Fallible + ?Sized> rkyv::Deserialize<SmallString, D>
128    for rkyv::string::ArchivedString
129{
130    fn deserialize(&self, _deserializer: &mut D) -> Result<SmallString, D::Error> {
131        Ok(SmallString::from(self.as_str()))
132    }
133}
134
135impl PartialEq<SmallString> for rkyv::string::ArchivedString {
136    fn eq(&self, other: &SmallString) -> bool {
137        **other == **self
138    }
139}
140
141impl PartialOrd<SmallString> for rkyv::string::ArchivedString {
142    fn partial_cmp(&self, other: &SmallString) -> Option<::core::cmp::Ordering> {
143        Some(self.as_str().cmp(other))
144    }
145}
146
147/// An [`schemars::JsonSchema`] implementation for [`SmallString`].
148#[cfg(feature = "schemars")]
149impl schemars::JsonSchema for SmallString {
150    fn inline_schema() -> bool {
151        true
152    }
153
154    fn schema_name() -> Cow<'static, str> {
155        String::schema_name()
156    }
157
158    fn json_schema(generator: &mut schemars::generate::SchemaGenerator) -> schemars::Schema {
159        String::json_schema(generator)
160    }
161}