@@ -29,6 +29,80 @@ mod bits;
29
29
mod memcmp;
30
30
31
31
use memchr:: memchr;
32
+ use std:: rc:: Rc ;
33
+ use std:: sync:: Arc ;
34
+
35
+ /// Needle that can be searched for within a haystack. It allows specialized
36
+ /// searcher implementations for needle sizes known at compile time.
37
+ pub trait Needle {
38
+ /// Set to `Some(<usize>)` if and only if the needle's length is known at compile time.
39
+ const SIZE : Option < usize > ;
40
+ /// Return the slice corresponding to the needle.
41
+ fn as_bytes ( & self ) -> & [ u8 ] ;
42
+ }
43
+
44
+ impl < const N : usize > Needle for [ u8 ; N ] {
45
+ const SIZE : Option < usize > = Some ( N ) ;
46
+
47
+ #[ inline]
48
+ fn as_bytes ( & self ) -> & [ u8 ] {
49
+ self
50
+ }
51
+ }
52
+
53
+ impl Needle for [ u8 ] {
54
+ const SIZE : Option < usize > = None ;
55
+
56
+ #[ inline]
57
+ fn as_bytes ( & self ) -> & [ u8 ] {
58
+ self
59
+ }
60
+ }
61
+
62
+ impl < N : Needle + ?Sized > Needle for Box < N > {
63
+ const SIZE : Option < usize > = N :: SIZE ;
64
+
65
+ #[ inline]
66
+ fn as_bytes ( & self ) -> & [ u8 ] {
67
+ ( * * self ) . as_bytes ( )
68
+ }
69
+ }
70
+
71
+ impl < N : Needle + ?Sized > Needle for Rc < N > {
72
+ const SIZE : Option < usize > = N :: SIZE ;
73
+
74
+ #[ inline]
75
+ fn as_bytes ( & self ) -> & [ u8 ] {
76
+ ( * * self ) . as_bytes ( )
77
+ }
78
+ }
79
+
80
+ impl < N : Needle + ?Sized > Needle for Arc < N > {
81
+ const SIZE : Option < usize > = N :: SIZE ;
82
+
83
+ #[ inline]
84
+ fn as_bytes ( & self ) -> & [ u8 ] {
85
+ ( * * self ) . as_bytes ( )
86
+ }
87
+ }
88
+
89
+ impl < N : Needle + ?Sized > Needle for & N {
90
+ const SIZE : Option < usize > = N :: SIZE ;
91
+
92
+ #[ inline]
93
+ fn as_bytes ( & self ) -> & [ u8 ] {
94
+ ( * self ) . as_bytes ( )
95
+ }
96
+ }
97
+
98
+ impl Needle for Vec < u8 > {
99
+ const SIZE : Option < usize > = None ;
100
+
101
+ #[ inline]
102
+ fn as_bytes ( & self ) -> & [ u8 ] {
103
+ self
104
+ }
105
+ }
32
106
33
107
/// Single-byte searcher using `memchr` for faster matching.
34
108
pub struct MemchrSearcher ( u8 ) ;
@@ -57,7 +131,7 @@ impl MemchrSearcher {
57
131
58
132
#[ cfg( test) ]
59
133
mod tests {
60
- use super :: MemchrSearcher ;
134
+ use super :: { MemchrSearcher , Needle } ;
61
135
62
136
fn memchr_search ( haystack : & [ u8 ] , needle : & [ u8 ] ) -> bool {
63
137
MemchrSearcher :: new ( needle[ 0 ] ) . search_in ( haystack)
@@ -92,4 +166,36 @@ mod tests {
92
166
fn memchr_search_middle ( ) {
93
167
assert ! ( memchr_search( b"foobarfoo" , b"b" ) ) ;
94
168
}
169
+
170
+ #[ test]
171
+ fn needle_array_size ( ) {
172
+ use std:: rc:: Rc ;
173
+ use std:: sync:: Arc ;
174
+
175
+ assert_eq ! ( <[ u8 ; 0 ] as Needle >:: SIZE , Some ( 0 ) ) ;
176
+
177
+ assert_eq ! ( Box :: <[ u8 ; 1 ] >:: SIZE , Some ( 1 ) ) ;
178
+
179
+ assert_eq ! ( Rc :: <[ u8 ; 2 ] >:: SIZE , Some ( 2 ) ) ;
180
+
181
+ assert_eq ! ( Arc :: <[ u8 ; 3 ] >:: SIZE , Some ( 3 ) ) ;
182
+
183
+ assert_eq ! ( <& [ u8 ; 4 ] as Needle >:: SIZE , Some ( 4 ) ) ;
184
+ }
185
+
186
+ #[ test]
187
+ fn needle_slice_size ( ) {
188
+ use std:: rc:: Rc ;
189
+ use std:: sync:: Arc ;
190
+
191
+ assert_eq ! ( Box :: <[ u8 ] >:: SIZE , None ) ;
192
+
193
+ assert_eq ! ( Vec :: <u8 >:: SIZE , None ) ;
194
+
195
+ assert_eq ! ( Rc :: <[ u8 ] >:: SIZE , None ) ;
196
+
197
+ assert_eq ! ( Arc :: <[ u8 ] >:: SIZE , None ) ;
198
+
199
+ assert_eq ! ( <& [ u8 ] as Needle >:: SIZE , None ) ;
200
+ }
95
201
}
0 commit comments