@@ -14,6 +14,7 @@ use super::util::StrUtil;
14
14
lazy_static ! {
15
15
static ref IDENT_RE : Regex = Regex :: new( r"^(\p{XID_Start}|_)\p{XID_Continue}*" ) . unwrap( ) ;
16
16
static ref LINE_RE : Regex = Regex :: new( r"^(.*?)(\n|\r\n?|$)" ) . unwrap( ) ;
17
+ static ref NONSPACE_RE : Regex = Regex :: new( r"^\S+" ) . unwrap( ) ;
17
18
static ref NUMBER_RE : Regex = Regex :: new( r"^\d+" ) . unwrap( ) ;
18
19
static ref WORD_RE : Regex = Regex :: new( r"^\w+" ) . unwrap( ) ;
19
20
static ref WORDISH_RE : Regex = Regex :: new( r"^(\d+|\w+|\S)" ) . unwrap( ) ;
@@ -149,6 +150,44 @@ fn test_line() {
149
150
assert_match ! ( Line :: scan_from( "abc\r def" ) , Ok ( ( "abc" , 4 ) ) ) ;
150
151
}
151
152
153
+ /**
154
+ Scans a sequence of non-space characters into a string.
155
+
156
+ This *will not* match an empty sequence; there must be at least one non-space character for the scan to succeed.
157
+ */
158
+ pub struct NonSpace < ' a , Output =& ' a str > ( PhantomData < ( & ' a ( ) , Output ) > ) ;
159
+
160
+ impl < ' a , Output > ScanFromStr < ' a > for NonSpace < ' a , Output > where & ' a str : Into < Output > {
161
+ type Output = Output ;
162
+ fn scan_from ( s : & ' a str ) -> Result < ( Self :: Output , usize ) , ScanErrorKind > {
163
+ match NONSPACE_RE . find ( s) {
164
+ Some ( ( a, b) ) => {
165
+ let word = & s[ a..b] ;
166
+ let tail = & s[ b..] ;
167
+ Ok ( ( word. into ( ) , s. subslice_offset ( tail) . unwrap ( ) ) )
168
+ } ,
169
+ None => Err ( ScanErrorKind :: Missing ) ,
170
+ }
171
+ }
172
+ }
173
+
174
+ #[ cfg( test) ]
175
+ #[ test]
176
+ fn test_non_space ( ) {
177
+ use :: ScanErrorKind as SEK ;
178
+
179
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "" ) , Err ( SEK :: Missing ) ) ;
180
+ assert_match ! ( NonSpace :: <& str >:: scan_from( " abc " ) , Err ( SEK :: Missing ) ) ;
181
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc " ) , Ok ( ( "abc" , 3 ) ) ) ;
182
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\t " ) , Ok ( ( "abc" , 3 ) ) ) ;
183
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\r " ) , Ok ( ( "abc" , 3 ) ) ) ;
184
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\n " ) , Ok ( ( "abc" , 3 ) ) ) ;
185
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\u{a0} " ) , Ok ( ( "abc" , 3 ) ) ) ;
186
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\u{2003} " ) , Ok ( ( "abc" , 3 ) ) ) ;
187
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\u{200B} " ) , Ok ( ( "abc\u{200b} " , 6 ) ) ) ;
188
+ assert_match ! ( NonSpace :: <& str >:: scan_from( "abc\u{3000} " ) , Ok ( ( "abc" , 3 ) ) ) ;
189
+ }
190
+
152
191
/**
153
192
Scans a single number into a string.
154
193
0 commit comments