hash_str/
ornaments.rs

1// === Ornaments ===
2// Bells and whistles.
3// Convenient impls which may obscure
4// the readability of the core implementations.
5
6use crate::hash::make_hash;
7use crate::hash_str::HashStr;
8
9impl AsRef<str> for HashStr{
10	#[inline]
11	fn as_ref(&self)->&str{
12		self.as_str()
13	}
14}
15impl core::ops::Deref for HashStr{
16	type Target=str;
17	#[inline]
18	fn deref(&self)->&Self::Target{
19		self.as_str()
20	}
21}
22
23impl core::fmt::Display for HashStr{
24	#[inline]
25	fn fmt(&self,f:&mut core::fmt::Formatter<'_>)->core::fmt::Result{
26		f.write_str(self.as_str())
27	}
28}
29
30impl PartialEq for HashStr{
31	#[inline]
32	fn eq(&self,other:&Self)->bool{
33		self.precomputed_hash()==other.precomputed_hash()&&self.as_str().eq(other.as_str())
34	}
35}
36impl Eq for HashStr{}
37// TODO: more PartialOrd impls e.g. PartialOrd<str>
38impl PartialOrd for HashStr{
39	#[inline]
40	fn partial_cmp(&self,other:&Self)->Option<core::cmp::Ordering>{
41		self.as_str().partial_cmp(other.as_str())
42	}
43}
44impl Ord for HashStr{
45	#[inline]
46	fn cmp(&self,other:&Self)->std::cmp::Ordering{
47		self.as_str().cmp(other.as_str())
48	}
49}
50
51/// Helper type for indexing a HashMap without allocation
52/// Unhashed str is hashed on the fly instead of using a precalculated hash.
53/// Useful for indexing a HashMap without needing to allocate a Box<HashStr>
54#[repr(transparent)]
55#[derive(Debug,PartialEq,Eq,PartialOrd,Ord)]
56pub struct UnhashedStr(str);
57impl UnhashedStr{
58	#[inline]
59	pub const fn from_ref<'a>(str:&'a str)->&'a Self{
60		// SAFETY: UnhashedStr is #[repr(transparent)]
61		let ptr=str as *const str as *const Self;
62		unsafe{&*ptr}
63	}
64	#[inline]
65	pub const fn as_str<'a>(&'a self)->&'a str{
66		// SAFETY: UnhashedStr is #[repr(transparent)]
67		let ptr=self as *const Self as *const str;
68		unsafe{&*ptr}
69	}
70}
71impl core::hash::Hash for UnhashedStr{
72	#[inline]
73	fn hash<H:std::hash::Hasher>(&self,state:&mut H){
74		let hash=make_hash(self.into());
75		state.write_u64(hash);
76	}
77}
78impl<'a> From<&'a str> for &'a UnhashedStr{
79	#[inline]
80	fn from(value:&'a str)->Self{
81		UnhashedStr::from_ref(value)
82	}
83}
84impl<'a> From<&'a UnhashedStr> for &'a str{
85	#[inline]
86	fn from(value:&'a UnhashedStr)->Self{
87		value.as_str()
88	}
89}
90
91impl core::borrow::Borrow<UnhashedStr> for &HashStr{
92	#[inline]
93	fn borrow(&self)->&UnhashedStr{
94		UnhashedStr::from_ref(self.as_str())
95	}
96}
97
98pub trait GetHash{
99	fn get_hash(self)->u64;
100}
101impl GetHash for &str{
102	#[inline]
103	fn get_hash(self)->u64{
104		make_hash(self)
105	}
106}
107impl GetHash for &HashStr{
108	#[inline]
109	fn get_hash(self)->u64{
110		self.precomputed_hash()
111	}
112}
113
114macro_rules! partial_eq_lhs_as_str{
115	($lhs:ty,$rhs:ty)=>{
116		impl PartialEq<$rhs> for $lhs {
117			#[inline]
118			fn eq(&self, other: &$rhs) -> bool {
119				self.as_str() == other
120			}
121		}
122		impl PartialEq<$lhs> for $rhs {
123			#[inline]
124			fn eq(&self, other: &$lhs) -> bool {
125				self == other.as_str()
126			}
127		}
128	};
129}
130macro_rules! partial_eq_lhs_as_str_rhs_deref{
131	($lhs:ty,$rhs:ty)=>{
132		impl PartialEq<$rhs> for $lhs {
133			#[inline]
134			fn eq(&self, &other: &$rhs) -> bool {
135				self.as_str() == other
136			}
137		}
138		impl PartialEq<$lhs> for $rhs {
139			#[inline]
140			fn eq(&self, other: &$lhs) -> bool {
141				*self == other.as_str()
142			}
143		}
144	};
145}
146macro_rules! partial_eq_lhs_as_str_rhs_as_ref{
147	($lhs:ty,$rhs:ty)=>{
148		impl PartialEq<$rhs> for $lhs {
149			#[inline]
150			fn eq(&self, other: &$rhs) -> bool {
151				self.as_str() == other.as_ref()
152			}
153		}
154		impl PartialEq<$lhs> for $rhs {
155			#[inline]
156			fn eq(&self, other: &$lhs) -> bool {
157				self.as_ref() == other.as_str()
158			}
159		}
160	};
161}
162partial_eq_lhs_as_str!(HashStr,str);
163partial_eq_lhs_as_str!(&HashStr,str);
164partial_eq_lhs_as_str!(HashStr,String);
165partial_eq_lhs_as_str!(&HashStr,String);
166partial_eq_lhs_as_str_rhs_deref!(HashStr,&str);
167partial_eq_lhs_as_str_rhs_deref!(HashStr,&String);
168partial_eq_lhs_as_str_rhs_as_ref!(HashStr,Box<str>);
169partial_eq_lhs_as_str_rhs_as_ref!(&HashStr,Box<str>);
170partial_eq_lhs_as_str_rhs_as_ref!(HashStr,&Box<str>);
171use std::borrow::Cow;
172partial_eq_lhs_as_str_rhs_as_ref!(HashStr,Cow<'_,str>);
173partial_eq_lhs_as_str_rhs_as_ref!(&HashStr,Cow<'_,str>);
174partial_eq_lhs_as_str_rhs_as_ref!(HashStr,&Cow<'_,str>);
175
176// TODO:
177// Path and OsStr requre CStr
178// use std::path::Path;
179// use std::ffi::OsStr;