@@ -93,6 +93,66 @@ impl ngx_str_t {
9393 len : data. len ( ) ,
9494 }
9595 }
96+
97+ /// Divides one `ngx_str_t` into two at an index.
98+ ///
99+ /// # Safety
100+ ///
101+ /// The results will reference the original string; be wary of the ownership and lifetime.
102+ pub fn split_at ( & self , mid : usize ) -> Option < ( ngx_str_t , ngx_str_t ) > {
103+ if mid > self . len {
104+ return None ;
105+ }
106+
107+ Some ( (
108+ ngx_str_t {
109+ data : self . data ,
110+ len : mid,
111+ } ,
112+ ngx_str_t {
113+ data : unsafe { self . data . add ( mid) } ,
114+ len : self . len - mid,
115+ } ,
116+ ) )
117+ }
118+
119+ /// Returns an `ngx_str_t` with the prefix removed.
120+ ///
121+ /// If the string starts with the byte sequence `prefix`, returns the substring after the
122+ /// prefix, wrapped in `Some`. The resulting substring can be empty.
123+ ///
124+ /// # Safety
125+ ///
126+ /// The result will reference the original string; be wary of the ownership and lifetime.
127+ ///
128+ /// The method is not marked as `unsafe` as everything it does is possible via safe interfaces.
129+ pub fn strip_prefix ( & self , prefix : impl AsRef < [ u8 ] > ) -> Option < ngx_str_t > {
130+ let prefix = prefix. as_ref ( ) ;
131+ if self . as_bytes ( ) . starts_with ( prefix) {
132+ self . split_at ( prefix. len ( ) ) . map ( |x| x. 1 )
133+ } else {
134+ None
135+ }
136+ }
137+
138+ /// Returns an `ngx_str_t` with the suffix removed.
139+ ///
140+ /// If the string ends with the byte sequence `suffix`, returns the substring before the
141+ /// suffix, wrapped in `Some`. The resulting substring can be empty.
142+ ///
143+ /// # Safety
144+ ///
145+ /// The result will reference the original string; be wary of the ownership and lifetime.
146+ ///
147+ /// The method is not marked as `unsafe` as everything it does is possible via safe interfaces.
148+ pub fn strip_suffix ( & self , suffix : impl AsRef < [ u8 ] > ) -> Option < ngx_str_t > {
149+ let suffix = suffix. as_ref ( ) ;
150+ if self . as_bytes ( ) . ends_with ( suffix) {
151+ self . split_at ( self . len - suffix. len ( ) ) . map ( |x| x. 0 )
152+ } else {
153+ None
154+ }
155+ }
96156}
97157
98158impl AsRef < [ u8 ] > for ngx_str_t {
@@ -162,3 +222,31 @@ impl TryFrom<ngx_str_t> for &str {
162222 str:: from_utf8 ( s. into ( ) )
163223 }
164224}
225+
226+ #[ cfg( test) ]
227+ mod tests {
228+ use super :: * ;
229+
230+ #[ test]
231+ fn ngx_str_prefix ( ) {
232+ let s = "key=value" ;
233+ let s = ngx_str_t {
234+ data : s. as_ptr ( ) . cast_mut ( ) ,
235+ len : s. len ( ) ,
236+ } ;
237+
238+ assert_eq ! (
239+ s. strip_prefix( "key=" ) . as_ref( ) . map( ngx_str_t:: as_bytes) ,
240+ Some ( "value" . as_bytes( ) )
241+ ) ;
242+
243+ assert_eq ! ( s. strip_prefix( "test" ) , None ) ;
244+
245+ assert_eq ! (
246+ s. strip_suffix( "value" ) . as_ref( ) . map( ngx_str_t:: as_bytes) ,
247+ Some ( "key=" . as_bytes( ) )
248+ ) ;
249+
250+ assert_eq ! ( s. strip_suffix( "test" ) , None ) ;
251+ }
252+ }
0 commit comments