55 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" ,
66 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
77) ]
8- #![ forbid ( unsafe_code) ]
8+ #![ deny ( unsafe_code) ]
99#![ warn(
1010 clippy:: mod_module_files,
1111 clippy:: unwrap_used,
@@ -36,23 +36,34 @@ const INVARIANT_MSG: &str = "should be ensured valid by constructor";
3636/// e.g. `$<id>$...`.
3737///
3838/// For more information, see [`PasswordHash`].
39- #[ derive( Clone , Copy , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
40- pub struct PasswordHashRef < ' a > ( & ' a str ) ;
39+ #[ derive( Debug , Eq , PartialEq , PartialOrd , Ord ) ]
40+ #[ repr( transparent) ]
41+ pub struct PasswordHashRef ( str ) ;
4142
42- impl < ' a > PasswordHashRef < ' a > {
43+ impl PasswordHashRef {
4344 /// Parse the given input string, returning an [`PasswordHashRef`] if valid.
44- pub fn new ( s : & ' a str ) -> Result < Self > {
45+ pub fn new ( s : & str ) -> Result < & PasswordHashRef > {
4546 validate ( s) ?;
46- Ok ( Self ( s) )
47+ Ok ( Self :: new_unchecked ( s) )
48+ }
49+
50+ /// Construct a new [`PasswordHashRef`] string from the given input `str` reference without
51+ /// first asserting its validity.
52+ fn new_unchecked ( s : & str ) -> & PasswordHashRef {
53+ // SAFETY: `Self` is a `repr(transparent)` newtype for `str`
54+ #[ allow( unsafe_code) ]
55+ unsafe {
56+ & * ( s as * const str as * const Self )
57+ }
4758 }
4859
4960 /// Get the contained string as a `str`.
50- pub fn as_str ( self ) -> & ' a str {
51- self . 0
61+ pub fn as_str ( & self ) -> & str {
62+ & self . 0
5263 }
5364
5465 /// Get the algorithm identifier for this MCF hash.
55- pub fn id ( self ) -> & ' a str {
66+ pub fn id ( & self ) -> & str {
5667 Fields :: new ( self . as_str ( ) )
5768 . next ( )
5869 . expect ( INVARIANT_MSG )
@@ -61,7 +72,7 @@ impl<'a> PasswordHashRef<'a> {
6172
6273 /// Get an iterator over the parts of the password hash as delimited by `$`, excluding the
6374 /// initial identifier.
64- pub fn fields ( self ) -> Fields < ' a > {
75+ pub fn fields ( & self ) -> Fields < ' _ > {
6576 let mut fields = Fields :: new ( self . as_str ( ) ) ;
6677
6778 // Remove the leading identifier
@@ -72,38 +83,40 @@ impl<'a> PasswordHashRef<'a> {
7283 }
7384}
7485
75- impl fmt :: Display for PasswordHashRef < ' _ > {
76- fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
77- f . write_str ( self . as_str ( ) )
86+ impl AsRef < str > for & PasswordHashRef {
87+ fn as_ref ( & self ) -> & str {
88+ self . as_str ( )
7889 }
7990}
8091
81- impl < ' a > From < PasswordHashRef < ' a > > for & ' a str {
82- fn from ( hash : PasswordHashRef < ' a > ) -> & ' a str {
83- hash . 0
92+ impl fmt :: Display for PasswordHashRef {
93+ fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
94+ f . write_str ( self . as_str ( ) )
8495 }
8596}
8697
87- #[ cfg( feature = "alloc" ) ]
88- impl From < PasswordHashRef < ' _ > > for alloc:: string:: String {
89- fn from ( hash : PasswordHashRef < ' _ > ) -> Self {
90- hash. 0 . into ( )
98+ impl < ' a > From < & ' a PasswordHashRef > for & ' a str {
99+ fn from ( hash : & ' a PasswordHashRef ) -> & ' a str {
100+ hash. as_str ( )
91101 }
92102}
93103
94- impl < ' a > TryFrom < & ' a str > for PasswordHashRef < ' a > {
104+ impl < ' a > TryFrom < & ' a str > for & ' a PasswordHashRef {
95105 type Error = Error ;
96106
97107 fn try_from ( s : & ' a str ) -> Result < Self > {
98- Self :: new ( s)
108+ PasswordHashRef :: new ( s)
99109 }
100110}
101111
102112#[ cfg( feature = "alloc" ) ]
103113mod allocating {
104- use crate :: { Error , Field , Fields , PasswordHashRef , Result , fields, validate, validate_id} ;
105- use alloc:: string:: { String , ToString } ;
106- use core:: { fmt, str} ;
114+ use crate :: { Error , Field , PasswordHashRef , Result , fields, validate, validate_id} ;
115+ use alloc:: {
116+ borrow:: ToOwned ,
117+ string:: { String , ToString } ,
118+ } ;
119+ use core:: { borrow:: Borrow , fmt, ops:: Deref , str:: FromStr } ;
107120
108121 #[ cfg( feature = "base64" ) ]
109122 use crate :: Base64 ;
@@ -152,27 +165,6 @@ mod allocating {
152165 Ok ( Self ( hash) )
153166 }
154167
155- /// Get the contained string as a `str`.
156- pub fn as_str ( & self ) -> & str {
157- & self . 0
158- }
159-
160- /// Get an [`PasswordHashRef`] which corresponds to this owned [`PasswordHash`].
161- pub fn as_mcf_hash_ref ( & self ) -> PasswordHashRef < ' _ > {
162- PasswordHashRef ( self . as_str ( ) )
163- }
164-
165- /// Get the algorithm identifier for this MCF hash.
166- pub fn id ( & self ) -> & str {
167- self . as_mcf_hash_ref ( ) . id ( )
168- }
169-
170- /// Get an iterator over the parts of the password hash as delimited by `$`, excluding the
171- /// initial identifier.
172- pub fn fields ( & self ) -> Fields < ' _ > {
173- self . as_mcf_hash_ref ( ) . fields ( )
174- }
175-
176168 /// Encode the given data as the specified variant of Base64 and push it onto the password
177169 /// hash string, first adding a `$` delimiter.
178170 #[ cfg( feature = "base64" ) ]
@@ -207,15 +199,29 @@ mod allocating {
207199 }
208200 }
209201
210- impl < ' a > AsRef < str > for PasswordHashRef < ' a > {
202+ impl AsRef < str > for PasswordHash {
211203 fn as_ref ( & self ) -> & str {
212- self . as_str ( )
204+ self . 0 . as_str ( )
213205 }
214206 }
215207
216- impl AsRef < str > for PasswordHash {
217- fn as_ref ( & self ) -> & str {
218- self . as_str ( )
208+ impl AsRef < PasswordHashRef > for PasswordHash {
209+ fn as_ref ( & self ) -> & PasswordHashRef {
210+ PasswordHashRef :: new_unchecked ( & self . 0 )
211+ }
212+ }
213+
214+ impl Borrow < PasswordHashRef > for PasswordHash {
215+ fn borrow ( & self ) -> & PasswordHashRef {
216+ self . as_ref ( )
217+ }
218+ }
219+
220+ impl Deref for PasswordHash {
221+ type Target = PasswordHashRef ;
222+
223+ fn deref ( & self ) -> & PasswordHashRef {
224+ self . as_ref ( )
219225 }
220226 }
221227
@@ -225,6 +231,14 @@ mod allocating {
225231 }
226232 }
227233
234+ impl FromStr for PasswordHash {
235+ type Err = Error ;
236+
237+ fn from_str ( s : & str ) -> Result < Self > {
238+ Self :: new ( s)
239+ }
240+ }
241+
228242 impl TryFrom < String > for PasswordHash {
229243 type Error = Error ;
230244
@@ -247,11 +261,33 @@ mod allocating {
247261 }
248262 }
249263
250- impl str:: FromStr for PasswordHash {
251- type Err = Error ;
264+ //
265+ // PasswordHashRef extensions
266+ //
252267
253- fn from_str ( s : & str ) -> Result < Self > {
254- Self :: new ( s)
268+ impl < ' a > From < & ' a PasswordHash > for & ' a PasswordHashRef {
269+ fn from ( hash : & ' a PasswordHash ) -> & ' a PasswordHashRef {
270+ hash. as_ref ( )
271+ }
272+ }
273+
274+ impl From < & PasswordHashRef > for PasswordHash {
275+ fn from ( hash : & PasswordHashRef ) -> Self {
276+ PasswordHash ( hash. into ( ) )
277+ }
278+ }
279+
280+ impl From < & PasswordHashRef > for String {
281+ fn from ( hash : & PasswordHashRef ) -> Self {
282+ hash. 0 . into ( )
283+ }
284+ }
285+
286+ impl ToOwned for PasswordHashRef {
287+ type Owned = PasswordHash ;
288+
289+ fn to_owned ( & self ) -> PasswordHash {
290+ self . into ( )
255291 }
256292 }
257293}
0 commit comments