qp_trie/
wrapper.rs

1use alloc::borrow::ToOwned;
2use alloc::string::String;
3use core::borrow::Borrow;
4use core::fmt;
5use core::hash::{Hash, Hasher};
6use core::ops::Deref;
7
8use trie::Break;
9
10/// A wrapper for `String` which implements `Borrow<[u8]>` and hashes in the same way as a byte
11/// slice.
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
14pub struct BString(String);
15
16impl fmt::Debug for BString {
17    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18        self.0.fmt(f)
19    }
20}
21
22impl From<BString> for String {
23    #[inline]
24    fn from(bs: BString) -> String {
25        bs.0
26    }
27}
28
29impl From<String> for BString {
30    #[inline]
31    fn from(s: String) -> BString {
32        BString(s)
33    }
34}
35
36impl<'a> From<&'a str> for BString {
37    #[inline]
38    fn from(s: &'a str) -> BString {
39        BString(s.into())
40    }
41}
42
43impl Deref for BString {
44    type Target = BStr;
45
46    #[inline]
47    fn deref(&self) -> &Self::Target {
48        From::from(self.0.as_str())
49    }
50}
51
52impl Borrow<BStr> for BString {
53    #[inline]
54    fn borrow(&self) -> &BStr {
55        self
56    }
57}
58
59impl Borrow<[u8]> for BString {
60    #[inline]
61    fn borrow(&self) -> &[u8] {
62        self.0.as_bytes()
63    }
64}
65
66#[allow(clippy::derived_hash_with_manual_eq)]
67impl Hash for BString {
68    #[inline]
69    fn hash<H: Hasher>(&self, state: &mut H) {
70        self.0.as_bytes().hash(state);
71    }
72}
73
74impl Break for BString {
75    type Split = BStr;
76
77    #[inline]
78    fn empty<'a>() -> &'a BStr {
79        BStr::empty()
80    }
81
82    #[inline]
83    fn find_break(&self, loc: usize) -> &BStr {
84        (**self).find_break(loc)
85    }
86}
87
88/// A wrapper type for `str` which implements `Borrow<[u8]>` and hashes in the same way as a byte
89/// slice.
90#[derive(PartialEq, Eq, PartialOrd, Ord)]
91pub struct BStr(str);
92
93impl fmt::Debug for BStr {
94    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95        self.0.fmt(f)
96    }
97}
98
99impl<'a> From<&'a str> for &'a BStr {
100    fn from(s: &'a str) -> &'a BStr {
101        unsafe { &*(s as *const str as *const BStr) }
102    }
103}
104
105impl ToOwned for BStr {
106    type Owned = BString;
107
108    #[inline]
109    fn to_owned(&self) -> BString {
110        self.0.to_owned().into()
111    }
112}
113
114impl Borrow<[u8]> for BStr {
115    #[inline]
116    fn borrow(&self) -> &[u8] {
117        self.0.as_bytes()
118    }
119}
120
121#[allow(clippy::derived_hash_with_manual_eq)]
122impl Hash for BStr {
123    #[inline]
124    fn hash<H: Hasher>(&self, state: &mut H) {
125        self.0.as_bytes().hash(state);
126    }
127}
128
129impl Break for BStr {
130    type Split = BStr;
131
132    #[inline]
133    fn empty<'a>() -> &'a BStr {
134        <&'a BStr>::from(<&'a str>::default())
135    }
136
137    #[inline]
138    fn find_break(&self, mut loc: usize) -> &BStr {
139        while !self.0.is_char_boundary(loc) {
140            loc -= 1;
141        }
142
143        From::from(&self.as_str()[..loc])
144    }
145}
146
147impl BStr {
148    #[inline]
149    pub fn as_str(&self) -> &str {
150        &self.0
151    }
152}
153
154impl AsRef<BStr> for str {
155    fn as_ref(&self) -> &BStr {
156        <&BStr>::from(self)
157    }
158}