1 /// A UTF-8-encoded fixed string 2 /// 3 /// **NOTE:** To support dynamic values (i.e. `String`), enable the [`string` 4 /// feature][crate::_features] 5 #[derive(Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] 6 pub struct Str { 7 name: Inner, 8 } 9 10 impl Str { 11 #[cfg(feature = "string")] 12 pub(crate) fn from_string(name: std::string::String) -> Self { 13 Self { 14 name: Inner::from_string(name), 15 } 16 } 17 18 #[cfg(feature = "string")] 19 pub(crate) fn from_ref(name: &str) -> Self { 20 Self { 21 name: Inner::from_ref(name), 22 } 23 } 24 25 pub(crate) fn from_static_ref(name: &'static str) -> Self { 26 Self { 27 name: Inner::from_static_ref(name), 28 } 29 } 30 31 pub(crate) fn into_inner(self) -> Inner { 32 self.name 33 } 34 35 /// Get the raw string of the `Str` as_strnull36 pub fn as_str(&self) -> &str { 37 self.name.as_str() 38 } 39 } 40 41 impl From<&'_ Str> for Str { fromnull42 fn from(id: &'_ Str) -> Self { 43 id.clone() 44 } 45 } 46 47 #[cfg(feature = "string")] 48 impl From<std::string::String> for Str { 49 fn from(name: std::string::String) -> Self { 50 Self::from_string(name) 51 } 52 } 53 54 #[cfg(feature = "string")] 55 impl From<&'_ std::string::String> for Str { fromnull56 fn from(name: &'_ std::string::String) -> Self { 57 Self::from_ref(name.as_str()) 58 } 59 } 60 61 impl From<&'static str> for Str { 62 fn from(name: &'static str) -> Self { 63 Self::from_static_ref(name) 64 } 65 } 66 67 impl From<&'_ &'static str> for Str { 68 fn from(name: &'_ &'static str) -> Self { 69 Self::from_static_ref(name) 70 } 71 } 72 73 impl From<Str> for String { fromnull74 fn from(name: Str) -> Self { 75 name.name.into_string() 76 } 77 } 78 79 impl From<Str> for Vec<u8> { fromnull80 fn from(name: Str) -> Self { 81 String::from(name).into() 82 } 83 } 84 85 impl From<Str> for std::ffi::OsString { fromnull86 fn from(name: Str) -> Self { 87 String::from(name).into() 88 } 89 } 90 91 impl From<Str> for std::path::PathBuf { fromnull92 fn from(name: Str) -> Self { 93 String::from(name).into() 94 } 95 } 96 97 impl std::fmt::Display for Str { 98 #[inline] fmtnull99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 100 std::fmt::Display::fmt(self.as_str(), f) 101 } 102 } 103 104 impl std::fmt::Debug for Str { 105 #[inline] 106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 107 std::fmt::Debug::fmt(self.as_str(), f) 108 } 109 } 110 111 impl std::ops::Deref for Str { 112 type Target = str; 113 114 #[inline] derefnull115 fn deref(&self) -> &str { 116 self.as_str() 117 } 118 } 119 120 impl AsRef<str> for Str { 121 #[inline] as_refnull122 fn as_ref(&self) -> &str { 123 self.as_str() 124 } 125 } 126 127 impl AsRef<[u8]> for Str { 128 #[inline] as_refnull129 fn as_ref(&self) -> &[u8] { 130 self.as_bytes() 131 } 132 } 133 134 impl AsRef<std::ffi::OsStr> for Str { 135 #[inline] as_refnull136 fn as_ref(&self) -> &std::ffi::OsStr { 137 (**self).as_ref() 138 } 139 } 140 141 impl AsRef<std::path::Path> for Str { 142 #[inline] as_refnull143 fn as_ref(&self) -> &std::path::Path { 144 std::path::Path::new(self) 145 } 146 } 147 148 impl std::borrow::Borrow<str> for Str { 149 #[inline] borrownull150 fn borrow(&self) -> &str { 151 self.as_str() 152 } 153 } 154 155 impl PartialEq<str> for Str { 156 #[inline] eqnull157 fn eq(&self, other: &str) -> bool { 158 PartialEq::eq(self.as_str(), other) 159 } 160 } 161 impl PartialEq<Str> for str { 162 #[inline] eqnull163 fn eq(&self, other: &Str) -> bool { 164 PartialEq::eq(self, other.as_str()) 165 } 166 } 167 168 impl PartialEq<&'_ str> for Str { 169 #[inline] eqnull170 fn eq(&self, other: &&str) -> bool { 171 PartialEq::eq(self.as_str(), *other) 172 } 173 } 174 impl PartialEq<Str> for &'_ str { 175 #[inline] eqnull176 fn eq(&self, other: &Str) -> bool { 177 PartialEq::eq(*self, other.as_str()) 178 } 179 } 180 181 impl PartialEq<std::ffi::OsStr> for Str { 182 #[inline] eqnull183 fn eq(&self, other: &std::ffi::OsStr) -> bool { 184 PartialEq::eq(self.as_str(), other) 185 } 186 } 187 impl PartialEq<Str> for std::ffi::OsStr { 188 #[inline] eqnull189 fn eq(&self, other: &Str) -> bool { 190 PartialEq::eq(self, other.as_str()) 191 } 192 } 193 194 impl PartialEq<&'_ std::ffi::OsStr> for Str { 195 #[inline] eqnull196 fn eq(&self, other: &&std::ffi::OsStr) -> bool { 197 PartialEq::eq(self.as_str(), *other) 198 } 199 } 200 impl PartialEq<Str> for &'_ std::ffi::OsStr { 201 #[inline] eqnull202 fn eq(&self, other: &Str) -> bool { 203 PartialEq::eq(*self, other.as_str()) 204 } 205 } 206 207 impl PartialEq<std::string::String> for Str { 208 #[inline] eqnull209 fn eq(&self, other: &std::string::String) -> bool { 210 PartialEq::eq(self.as_str(), other.as_str()) 211 } 212 } 213 impl PartialEq<Str> for std::string::String { 214 #[inline] eqnull215 fn eq(&self, other: &Str) -> bool { 216 PartialEq::eq(self.as_str(), other.as_str()) 217 } 218 } 219 220 #[cfg(feature = "string")] 221 pub(crate) mod inner { 222 #[derive(Clone)] 223 pub(crate) enum Inner { 224 Static(&'static str), 225 Owned(Box<str>), 226 } 227 228 impl Inner { 229 pub(crate) fn from_string(name: std::string::String) -> Self { 230 Self::Owned(name.into_boxed_str()) 231 } 232 233 pub(crate) fn from_ref(name: &str) -> Self { 234 Self::Owned(Box::from(name)) 235 } 236 237 pub(crate) fn from_static_ref(name: &'static str) -> Self { 238 Self::Static(name) 239 } 240 241 pub(crate) fn as_str(&self) -> &str { 242 match self { 243 Self::Static(s) => s, 244 Self::Owned(s) => s.as_ref(), 245 } 246 } 247 248 pub(crate) fn into_string(self) -> String { 249 match self { 250 Self::Static(s) => s.to_owned(), 251 Self::Owned(s) => s.into(), 252 } 253 } 254 } 255 } 256 257 #[cfg(not(feature = "string"))] 258 pub(crate) mod inner { 259 #[derive(Clone)] 260 pub(crate) struct Inner(pub(crate) &'static str); 261 262 impl Inner { 263 pub(crate) fn from_static_ref(name: &'static str) -> Self { 264 Self(name) 265 } 266 267 pub(crate) fn as_str(&self) -> &str { 268 self.0 269 } 270 271 pub(crate) fn into_string(self) -> String { 272 self.as_str().to_owned() 273 } 274 } 275 } 276 277 pub(crate) use inner::Inner; 278 279 impl Default for Inner { defaultnull280 fn default() -> Self { 281 Self::from_static_ref("") 282 } 283 } 284 285 impl PartialEq for Inner { eqnull286 fn eq(&self, other: &Inner) -> bool { 287 self.as_str() == other.as_str() 288 } 289 } 290 291 impl PartialOrd for Inner { partial_cmpnull292 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { 293 self.as_str().partial_cmp(other.as_str()) 294 } 295 } 296 297 impl Ord for Inner { cmpnull298 fn cmp(&self, other: &Inner) -> std::cmp::Ordering { 299 self.as_str().cmp(other.as_str()) 300 } 301 } 302 303 impl Eq for Inner {} 304 305 impl std::hash::Hash for Inner { 306 #[inline] hashnull307 fn hash<H: std::hash::Hasher>(&self, state: &mut H) { 308 self.as_str().hash(state); 309 } 310 } 311