1
1
#[ cfg( all( not( feature = "std" ) , feature = "alloc" ) ) ]
2
2
use alloc:: { borrow:: Cow , string:: String } ;
3
+ use core:: cmp;
3
4
use core:: fmt;
4
5
use core:: str:: { self , Utf8Error } ;
5
6
#[ cfg( feature = "std" ) ]
@@ -25,6 +26,7 @@ macro_rules! ngx_string {
25
26
/// Representation of a borrowed [Nginx string].
26
27
///
27
28
/// [Nginx string]: https://nginx.org/en/docs/dev/development_guide.html#string_overview
29
+ #[ derive( Hash , PartialEq , Eq , PartialOrd , Ord ) ]
28
30
#[ repr( transparent) ]
29
31
pub struct NgxStr ( [ u_char ] ) ;
30
32
@@ -50,6 +52,13 @@ impl NgxStr {
50
52
unsafe { & * ( bytes as * const [ u8 ] as * const NgxStr ) }
51
53
}
52
54
55
+ /// Create a mutable [NgxStr] from a borrowed byte slice.
56
+ #[ inline]
57
+ pub fn from_bytes_mut ( bytes : & mut [ u8 ] ) -> & mut Self {
58
+ // SAFETY: An `NgxStr` is identical to a `[u8]` slice, given `u_char` is an alias for `u8`
59
+ unsafe { & mut * ( bytes as * mut [ u8 ] as * mut NgxStr ) }
60
+ }
61
+
53
62
/// Access the [`NgxStr`] as a byte slice.
54
63
pub fn as_bytes ( & self ) -> & [ u8 ] {
55
64
& self . 0
@@ -74,24 +83,20 @@ impl NgxStr {
74
83
}
75
84
}
76
85
77
- impl < ' a > From < & ' a [ u8 ] > for & ' a NgxStr {
78
- fn from ( bytes : & ' a [ u8 ] ) -> Self {
79
- NgxStr :: from_bytes ( bytes)
80
- }
81
- }
82
-
83
- impl < ' a > From < & ' a str > for & ' a NgxStr {
84
- fn from ( s : & ' a str ) -> Self {
85
- NgxStr :: from_bytes ( s. as_bytes ( ) )
86
- }
87
- }
88
-
89
86
impl AsRef < [ u8 ] > for NgxStr {
87
+ #[ inline]
90
88
fn as_ref ( & self ) -> & [ u8 ] {
91
89
self . as_bytes ( )
92
90
}
93
91
}
94
92
93
+ impl AsMut < [ u8 ] > for NgxStr {
94
+ #[ inline]
95
+ fn as_mut ( & mut self ) -> & mut [ u8 ] {
96
+ & mut self . 0
97
+ }
98
+ }
99
+
95
100
impl fmt:: Debug for NgxStr {
96
101
#[ inline]
97
102
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -115,6 +120,91 @@ impl fmt::Display for NgxStr {
115
120
}
116
121
}
117
122
123
+ macro_rules! impl_partial_ord_eq_from {
124
+ ( $self: ty, $other: ty) => { impl_partial_ord_eq_from!( $self, $other; ) ; } ;
125
+
126
+ ( $self: ty, $other: ty; $( $args: tt) * ) => {
127
+ impl <' a, $( $args) * > From <$other> for & ' a NgxStr {
128
+ #[ inline]
129
+ fn from( other: $other) -> Self {
130
+ let other: & [ u8 ] = other. as_ref( ) ;
131
+ NgxStr :: from_bytes( other)
132
+ }
133
+ }
134
+
135
+ impl_partial_eq!( $self, $other; $( $args) * ) ;
136
+ impl_partial_ord!( $self, $other; $( $args) * ) ;
137
+ } ;
138
+ }
139
+
140
+ macro_rules! impl_partial_eq {
141
+ ( $self: ty, $other: ty) => { impl_partial_eq!( $self, $other; ) ; } ;
142
+
143
+ ( $self: ty, $other: ty; $( $args: tt) * ) => {
144
+ impl <' a, $( $args) * > PartialEq <$other> for $self {
145
+ #[ inline]
146
+ fn eq( & self , other: & $other) -> bool {
147
+ let other: & [ u8 ] = other. as_ref( ) ;
148
+ PartialEq :: eq( self . as_bytes( ) , other)
149
+ }
150
+ }
151
+
152
+ impl <' a, $( $args) * > PartialEq <$self> for $other {
153
+ #[ inline]
154
+ fn eq( & self , other: & $self) -> bool {
155
+ let this: & [ u8 ] = self . as_ref( ) ;
156
+ PartialEq :: eq( this, other. as_bytes( ) )
157
+ }
158
+ }
159
+ } ;
160
+ }
161
+
162
+ macro_rules! impl_partial_ord {
163
+ ( $self: ty, $other: ty) => { impl_partial_ord!( $self, $other; ) ; } ;
164
+
165
+ ( $self: ty, $other: ty; $( $args: tt) * ) => {
166
+ impl <' a, $( $args) * > PartialOrd <$other> for $self {
167
+ #[ inline]
168
+ fn partial_cmp( & self , other: & $other) -> Option <cmp:: Ordering > {
169
+ let other: & [ u8 ] = other. as_ref( ) ;
170
+ PartialOrd :: partial_cmp( self . as_bytes( ) , other)
171
+ }
172
+ }
173
+
174
+ impl <' a, $( $args) * > PartialOrd <$self> for $other {
175
+ #[ inline]
176
+ fn partial_cmp( & self , other: & $self) -> Option <cmp:: Ordering > {
177
+ let this: & [ u8 ] = self . as_ref( ) ;
178
+ PartialOrd :: partial_cmp( this, other. as_bytes( ) )
179
+ }
180
+ }
181
+ } ;
182
+ }
183
+
184
+ impl_partial_eq ! ( NgxStr , [ u8 ] ) ;
185
+ impl_partial_eq ! ( NgxStr , [ u8 ; N ] ; const N : usize ) ;
186
+ impl_partial_eq ! ( NgxStr , str ) ;
187
+ impl_partial_eq ! ( NgxStr , ngx_str_t) ;
188
+ impl_partial_eq ! ( & ' a NgxStr , ngx_str_t) ;
189
+ impl_partial_ord ! ( NgxStr , [ u8 ] ) ;
190
+ impl_partial_ord ! ( NgxStr , [ u8 ; N ] ; const N : usize ) ;
191
+ impl_partial_ord ! ( NgxStr , str ) ;
192
+ impl_partial_ord ! ( NgxStr , ngx_str_t) ;
193
+ impl_partial_ord ! ( & ' a NgxStr , ngx_str_t) ;
194
+ impl_partial_ord_eq_from ! ( NgxStr , & ' a [ u8 ] ) ;
195
+ impl_partial_ord_eq_from ! ( NgxStr , & ' a [ u8 ; N ] ; const N : usize ) ;
196
+ impl_partial_ord_eq_from ! ( NgxStr , & ' a str ) ;
197
+
198
+ #[ cfg( feature = "alloc" ) ]
199
+ mod _alloc_impls {
200
+ use super :: * ;
201
+ impl_partial_eq ! ( NgxStr , String ) ;
202
+ impl_partial_eq ! ( & ' a NgxStr , String ) ;
203
+ impl_partial_ord ! ( NgxStr , String ) ;
204
+ impl_partial_ord ! ( & ' a NgxStr , String ) ;
205
+ impl_partial_ord_eq_from ! ( NgxStr , & ' a String ) ;
206
+ }
207
+
118
208
#[ cfg( test) ]
119
209
mod tests {
120
210
extern crate alloc;
@@ -123,6 +213,32 @@ mod tests {
123
213
124
214
use super :: * ;
125
215
216
+ #[ test]
217
+ fn test_comparisons ( ) {
218
+ let string = "test" . to_string ( ) ;
219
+ let ngx_string = ngx_str_t {
220
+ data : string. as_ptr ( ) . cast_mut ( ) ,
221
+ len : string. len ( ) ,
222
+ } ;
223
+ let ns: & NgxStr = string. as_bytes ( ) . into ( ) ;
224
+
225
+ #[ cfg( feature = "alloc" ) ]
226
+ assert_eq ! ( string, ns) ;
227
+ assert_eq ! ( ngx_string, ns) ;
228
+ assert_eq ! ( string. as_bytes( ) , ns) ;
229
+ assert_eq ! ( string. as_str( ) , ns) ;
230
+ assert_eq ! ( b"test" , ns) ;
231
+ assert_eq ! ( "test" , ns) ;
232
+
233
+ #[ cfg( feature = "alloc" ) ]
234
+ assert_eq ! ( ns, string) ;
235
+ assert_eq ! ( ns, ngx_string) ;
236
+ assert_eq ! ( ns, string. as_bytes( ) ) ;
237
+ assert_eq ! ( ns, string. as_str( ) ) ;
238
+ assert_eq ! ( ns, b"test" ) ;
239
+ assert_eq ! ( ns, "test" ) ;
240
+ }
241
+
126
242
#[ test]
127
243
fn test_lifetimes ( ) {
128
244
let a: & NgxStr = "Hello World!" . into ( ) ;
0 commit comments