use super::{Expression, ParseState, ParseResult};
macro_rules! fuse( ( $ex:expr ) => ( &base::Fuse::new( $ex ) ); );
pub struct Fuse<'a> {
expr: &'a ( Expression + 'a )
}
impl<'a> Fuse<'a> {
pub fn new( expr: & Expression ) -> Fuse {
Fuse { expr: expr }
}
}
impl<'b> Expression for Fuse<'b> {
fn apply<'a>( &self, parse_state: &ParseState<'a> ) ->
Option< ParseResult<'a> > {
self.expr.apply( parse_state ).and_then(
|result| parse_state.offsetToResult( result.parse_state.offset ) )
}
}
#[cfg(test)]
mod tests {
use base;
use base::{Node, Data, ParseResult, Expression};
#[test]
fn Fuse_Match_WithLiteralStar() {
let orig_state = input_state!( "ooo" );
match fuse!( plus!( lit!( "o" ) ) ).apply( &orig_state ) {
Some( ParseResult{ nodes, parse_state } ) => {
assert_eq!( nodes[ 0 ],
Node::withoutName( 0, 3, Data( b"ooo" ) ) );
assert_eq!( parse_state, orig_state.advanceTo( 3 ) );
}
_ => panic!( "No match." )
}
}
#[test]
fn Fuse_Match_WithCharClass() {
let orig_state = input_state!( "abc" );
match fuse!( plus!( class!( "a-z" ) ) ).apply( &orig_state ) {
Some( ParseResult{ nodes, parse_state } ) => {
assert_eq!( nodes[ 0 ],
Node::withoutName( 0, 3, Data( b"abc" ) ) );
assert_eq!( parse_state, orig_state.advanceTo( 3 ) );
}
_ => panic!( "No match." )
}
}
#[test]
fn Fuse_NoMatch() {
assert!( fuse!( class!( "a-z" ) ).apply( &input_state!( "5" ) ).is_none() );
assert!( fuse!( lit!( "x" ) ).apply( &input_state!( "g" ) ).is_none() );
}
}