Skip to main content

waterui_str/
impls.rs

1use core::fmt;
2use core::{
3    cmp::Ordering,
4    convert::Infallible,
5    fmt::Display,
6    hash::{Hash, Hasher},
7    mem::take,
8    ops::{Add, AddAssign, Deref, Index},
9    slice::SliceIndex,
10    str::FromStr,
11};
12
13use alloc::string::{String, ToString};
14
15use crate::Str;
16
17impl Hash for Str {
18    fn hash<H: Hasher>(&self, state: &mut H) {
19        self.deref().hash(state);
20    }
21}
22
23impl PartialEq for Str {
24    fn eq(&self, other: &Self) -> bool {
25        self.deref().eq(&**other)
26    }
27}
28
29impl PartialEq<&str> for Str {
30    fn eq(&self, other: &&str) -> bool {
31        self.deref().eq(*other)
32    }
33}
34
35impl PartialEq<str> for Str {
36    fn eq(&self, other: &str) -> bool {
37        self.deref().eq(other)
38    }
39}
40
41impl PartialEq<String> for Str {
42    fn eq(&self, other: &String) -> bool {
43        self.deref().eq(other)
44    }
45}
46
47impl PartialEq<Str> for &str {
48    fn eq(&self, other: &Str) -> bool {
49        (*self).eq(&**other)
50    }
51}
52
53impl PartialEq<Str> for str {
54    fn eq(&self, other: &Str) -> bool {
55        self.eq(&**other)
56    }
57}
58
59impl PartialEq<Str> for String {
60    fn eq(&self, other: &Str) -> bool {
61        self.eq(&**other)
62    }
63}
64
65impl<I: SliceIndex<str>> Index<I> for Str {
66    type Output = <I as SliceIndex<str>>::Output;
67    fn index(&self, index: I) -> &Self::Output {
68        self.deref().index(index)
69    }
70}
71
72impl FromStr for Str {
73    type Err = Infallible;
74    fn from_str(s: &str) -> Result<Self, Self::Err> {
75        Ok(Self::from(s.to_string()))
76    }
77}
78
79impl<S: AsRef<str>> FromIterator<S> for Str {
80    fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
81        iter.into_iter()
82            .fold(Self::new(), |state, s| state + s.as_ref())
83    }
84}
85
86impl Eq for Str {}
87
88impl PartialOrd for Str {
89    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
90        Some(self.cmp(other))
91    }
92}
93
94impl Ord for Str {
95    fn cmp(&self, other: &Self) -> Ordering {
96        self.deref().cmp(&**other)
97    }
98}
99
100impl Display for Str {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        self.deref().fmt(f)
103    }
104}
105
106/// Prints the string, the way every other string type does.
107///
108/// The derived implementation exposed the tagged representation instead — a
109/// raw pointer and a length that is negative whenever the string is owned — so
110/// `{:?}` on a `Str` produced `Str { ptr: .., len: -9 }`. That is unreadable
111/// where `Debug` matters most: assertion failures, tracing fields, and the
112/// `{:?}` of any type holding one.
113impl fmt::Debug for Str {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        fmt::Debug::fmt(&**self, f)
116    }
117}
118
119impl<'a> Extend<&'a str> for Str {
120    fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
121        self.handle(move |string| {
122            string.extend(iter);
123        });
124    }
125}
126
127impl Extend<String> for Str {
128    fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
129        self.handle(move |string| {
130            string.extend(iter);
131        });
132    }
133}
134
135impl Extend<Self> for Str {
136    fn extend<T: IntoIterator<Item = Self>>(&mut self, iter: T) {
137        self.handle(move |string| {
138            for s in iter {
139                string.push_str(&s);
140            }
141        });
142    }
143}
144
145impl<T> Add<T> for &Str
146where
147    T: AsRef<str>,
148{
149    type Output = Str;
150    fn add(self, rhs: T) -> Self::Output {
151        self.clone().add(rhs)
152    }
153}
154
155impl<T> Add<T> for Str
156where
157    T: AsRef<str>,
158{
159    type Output = Self;
160    fn add(self, rhs: T) -> Self::Output {
161        let rhs = rhs.as_ref();
162        (self.into_string() + rhs).into()
163    }
164}
165
166impl<T> AddAssign<T> for Str
167where
168    T: AsRef<str>,
169{
170    fn add_assign(&mut self, rhs: T) {
171        let rhs = rhs.as_ref();
172
173        let string = take(self).into_string();
174        *self = (string + rhs).into();
175    }
176}
177
178#[cfg(feature = "serde")]
179mod serde {
180    use core::fmt;
181    use core::ops::Deref;
182
183    use super::Str;
184    use alloc::string::{String, ToString};
185    use serde::{Deserialize, Deserializer, Serialize, de::Visitor};
186    struct StrVisitor;
187
188    impl Serialize for Str {
189        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
190        where
191            S: serde::Serializer,
192        {
193            self.deref().serialize(serializer)
194        }
195    }
196
197    impl Visitor<'_> for StrVisitor {
198        type Value = Str;
199
200        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
201            formatter.write_str("a string")
202        }
203
204        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
205            Ok(v.to_string().into())
206        }
207
208        fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
209            Ok(v.into())
210        }
211    }
212
213    impl<'de> Deserialize<'de> for Str {
214        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215        where
216            D: Deserializer<'de>,
217        {
218            deserializer.deserialize_string(StrVisitor)
219        }
220    }
221}