Skip to content

Commit 783e6a2

Browse files
committed
Added NonSpace scanner.
1 parent b9de175 commit 783e6a2

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/scanner/misc.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use super::util::StrUtil;
1414
lazy_static! {
1515
static ref IDENT_RE: Regex = Regex::new(r"^(\p{XID_Start}|_)\p{XID_Continue}*").unwrap();
1616
static ref LINE_RE: Regex = Regex::new(r"^(.*?)(\n|\r\n?|$)").unwrap();
17+
static ref NONSPACE_RE: Regex = Regex::new(r"^\S+").unwrap();
1718
static ref NUMBER_RE: Regex = Regex::new(r"^\d+").unwrap();
1819
static ref WORD_RE: Regex = Regex::new(r"^\w+").unwrap();
1920
static ref WORDISH_RE: Regex = Regex::new(r"^(\d+|\w+|\S)").unwrap();
@@ -149,6 +150,44 @@ fn test_line() {
149150
assert_match!(Line::scan_from("abc\rdef"), Ok(("abc", 4)));
150151
}
151152

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+
152191
/**
153192
Scans a single number into a string.
154193

src/scanner/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This module defines various abstract scanners that can be used to scan other typ
44
It is also where implementations for existing standard and external types are kept, though these do not appear in the documentation.
55
*/
66
pub use self::misc::{
7-
Everything,
7+
Everything, NonSpace,
88
Ident, Line, Number, Word, Wordish,
99
KeyValuePair, QuotedString,
1010
Binary, Octal, Hex,

0 commit comments

Comments
 (0)