scanner/macros: rewrite check! to be simpler to use, add isLineBreak!
This commit is contained in:
parent
3526cd29c4
commit
ba10beb0c6
|
@ -34,38 +34,62 @@ macro_rules! cow {
|
|||
/// cased to return an UnexpectedEOF if it encounters an
|
||||
/// empty slice
|
||||
macro_rules! check {
|
||||
($buffer:expr, $(@$pos:expr,)? is $( $byte:pat )|+ $(, else $error:expr)? ) => {
|
||||
{
|
||||
let b = match $buffer$([$pos..])? {
|
||||
[] => Err(false),
|
||||
$([$byte, ..])|+ => Ok(true),
|
||||
_ => Ok(false)
|
||||
(~ $buffer:expr $(, $offset:expr )? => $( $match:tt )|+ $(, else $error:expr)? ) => {
|
||||
check!(@priv $buffer.as_bytes() $(, $offset )? => $( $match )|+ $(, else $error)?)
|
||||
};
|
||||
|
||||
check!(@priv b $(=> $error)? )
|
||||
}
|
||||
};
|
||||
($buffer:expr, $(@$pos:expr,)? not $( $byte:pat )|+ $(, else $error:expr)? ) => {
|
||||
{
|
||||
let b = match $buffer$([$pos..])? {
|
||||
[] => Err(true),
|
||||
$([$byte, ..])|+ => Ok(false),
|
||||
_ => Ok(true)
|
||||
($buffer:expr $(, $offset:expr )? => $( $match:tt )|+ $(, else $error:expr)? ) => {
|
||||
check!(@priv $buffer $(, $offset )? => $( $match )|+ $(, else $error)?)
|
||||
};
|
||||
|
||||
check!(@priv b $(=> $error)? )
|
||||
/* Private variants */
|
||||
(@priv $buffer:expr, $offset:expr => $( $match:tt )|+) => {
|
||||
match $buffer.get($offset..) {
|
||||
Some(buffer) => check!(@priv buffer => $( $match )|+),
|
||||
None => false
|
||||
}
|
||||
};
|
||||
(@priv $bool:expr) => {
|
||||
match $bool {
|
||||
Ok(b) | Err(b) => b
|
||||
(@priv $buffer:expr => $( $match:tt )|+) => {
|
||||
match $buffer {
|
||||
$( check!(@ptn $match) )|+ => true,
|
||||
_ => false
|
||||
}
|
||||
};
|
||||
(@priv $bool:expr => $error:expr) => {
|
||||
match $bool {
|
||||
Ok(true) => Ok(()),
|
||||
Ok(false) => Err($error),
|
||||
Err(_) => Err($crate::scanner::error::ScanError::UnexpectedEOF),
|
||||
(@priv $buffer:expr, $offset:expr => $( $match:tt )|+, else $error:expr) => {
|
||||
match $buffer.get($offset..) {
|
||||
Some(buffer) => check!(@priv buffer => $( $match )|+ else $error),
|
||||
_ => Err($error)
|
||||
}
|
||||
};
|
||||
(@priv $buffer:expr => $( $match:tt )|+, else $error:expr) => {
|
||||
match $buffer {
|
||||
$( check!(@ptn $match) )|+ => Ok(()),
|
||||
[] => Err($crate::scanner::error::ScanError::UnexpectedEOF),
|
||||
_ => Err($error)
|
||||
}
|
||||
};
|
||||
|
||||
// Note we use macro path rules to first try matching the given
|
||||
// token as a literal, e.g a b'_', then try it as a pattern
|
||||
(@ptn $byte:literal) => {
|
||||
[$byte, ..]
|
||||
};
|
||||
(@ptn $match:pat) => {
|
||||
$match
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! isLineBreak {
|
||||
(~ $buffer:expr $(, $offset:expr )? ) => {
|
||||
isLineBreak!($buffer.as_bytes() $(, $offset )? )
|
||||
};
|
||||
($buffer:expr $(, $offset:expr )? ) => {
|
||||
check!($buffer $(, $offset)? =>
|
||||
b'\r' /* CR #xD */
|
||||
| b'\n' /* LF #xA */
|
||||
| [b'\xC2', b'\x85', ..] /* NEL #x85 */
|
||||
| [b'\xE2', b'\x80', b'\xA8', ..] /* LS #x2028 */
|
||||
| [b'\xE2', b'\x80', b'\xA9', ..] /* PS #x2029 */
|
||||
)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ impl<'a> Scanner<'a>
|
|||
{
|
||||
let mut buffer = self.buffer;
|
||||
|
||||
if check!(buffer.as_bytes(), not b'%')
|
||||
if !check!(~buffer => b'%')
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ impl<'a> Scanner<'a>
|
|||
|
||||
// %TAG !handle! tag-prefix # a comment \n
|
||||
// ^
|
||||
check!(buffer.as_bytes(), is b'!', else ScanError::InvalidTagHandle)?;
|
||||
check!(~buffer => b'!', else ScanError::InvalidTagHandle)?;
|
||||
|
||||
markers += 1;
|
||||
|
||||
|
@ -253,7 +253,7 @@ impl<'a> Scanner<'a>
|
|||
|
||||
// Check that there is >= 1 whitespace between handle and
|
||||
// prefix
|
||||
check!(buffer.as_bytes(), is b' ', else ScanError::InvalidTagPrefix)?;
|
||||
check!(~buffer => b' ', else ScanError::InvalidTagPrefix)?;
|
||||
|
||||
Self::eat_whitespace(&mut buffer, false);
|
||||
|
||||
|
@ -270,7 +270,7 @@ impl<'a> Scanner<'a>
|
|||
// %TAG !named! tag-prefix # a comment\n
|
||||
// ^
|
||||
// Check there is whitespace or a newline after the tag
|
||||
check!(buffer.as_bytes(), is b' ' | b'\n', else ScanError::InvalidTagPrefix)?;
|
||||
check!(~buffer => b' ' | b'\n', else ScanError::InvalidTagPrefix)?;
|
||||
|
||||
Token::TagDirective(cow!(handle), cow!(prefix))
|
||||
},
|
||||
|
@ -319,8 +319,9 @@ impl<'a> Scanner<'a>
|
|||
// There does not necessarily need to be a whitespace so we
|
||||
// also check against a list of valid starting
|
||||
// tokens
|
||||
check!(buffer.as_bytes(),
|
||||
is b' ' | b'\n' | b'?' | b',' | b']' | b'}' | b'%' | b'@' | b'`',
|
||||
|
||||
check!(~buffer
|
||||
=> b' ' | b'\n' | b'?' | b',' | b']' | b'}' | b'%' | b'@' | b'`',
|
||||
else ScanError::InvalidAnchorName
|
||||
)?;
|
||||
|
||||
|
|
Loading…
Reference in a new issue