Skip to content
Snippets Groups Projects
mod.rs 28.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • pub mod macros;
    
    #[cfg(test)]
    mod tests {
        use core::panic;
    
        use crate::combinators::common::characters::Char;
        use crate::parser::Parser;
    
    
        use crate::{parser_s};
    
        #[test]
        fn test_parser() -> Result<(), String> {        
            let p = Char {c: 'h'};
            match parser_s!((p)).parse("he") {
                Ok(c) => assert_eq!(c, 'h'),
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(p).parse("he") {
                Ok(c) => assert_eq!(c, 'h'),
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(((p))).parse("he") {
                Ok(c) => assert_eq!(c, 'h'),
                Err(e) => panic!("{}", e)
            }
    
            Ok(())
        }
    
    
    
        #[test]
        fn test_pure() -> Result<(), String>{
    
    
            match parser_s!(pure 1).parse("c") {
                Ok(_c) => (),
                Err(e) => panic!("{}", e) 
            }
    
            match parser_s!(pure (1 + 1)).parse("c") {
                Ok(_c) => (),
                Err(e) => panic!("{}", e) 
            }
    
            match parser_s!((pure (false))).parse("c") {
                Ok(_c) => (),
                Err(e) => panic!("{}", e) 
            }
    
            match parser_s!((pure 'l')).parse("c") {
                Ok(_c) => (),
                Err(e) => panic!("{}", e) 
            }
    
            match parser_s!(pure 1).parse("c") {
    
                Ok(_c) => Ok(()),
                Err(e) => panic!("{}", e) 
            }
        }
        
        #[test]
        fn test_empty() -> Result<(), String>{
    
    
            match parser_s!((empty)).parse("c") {
                Ok(e) => panic!("{}", e),
                Err(_s) => ()
            }
    
            match parser_s!(empty).parse("c") {
    
                Ok(e) => panic!("{}", e),
                Err(_s) => Ok(())
            }
        }
    
        #[test]
        fn test_sat() -> Result<(), String>{
    
            let f = |c:char| c == 'k';
    
            match parser_s!((sat (f))).parse("kb") {
                Ok(c) => assert_eq!(c, 'k'),
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!((sat f)).parse("kb") {
                Ok(c) => assert_eq!(c, 'k'),
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(sat (f)).parse("kb") {
                Ok(c) => assert_eq!(c, 'k'),
                Err(e) => panic!("{}", e)
            }
    
            let f = |c:char| c == 'k';
            match parser_s!(sat f).parse("kb") {
    
                Ok(c) => {
                    assert_eq!(c, 'k');
                    Ok(())
                },
                Err(e) => panic!("{}", e)
            }
        }
    
        fn test_char() -> Result<(), String> {
            match parser_s!('h').parse("he") {
                Ok(c) => assert_eq!(c, 'h'),
    
            match parser_s!(('h')).parse("he") {
                Ok(c) => assert_eq!(c, 'h'),
                Err(e) => panic!("{}", e)
            }
            
            let p = Char {c: 'h'};
            match parser_s!((p)).parse("he") {
                Ok(c) => assert_eq!(c, 'h'),
    
                Err(e) => panic!("{}", e)
            }
    
        fn test_zip_base() -> Result<(), String>{
    
            // Only literals
            match parser_s!('c'<~>'x').parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(('c'<~>'x')).parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
                Err(e) => panic!("{}", e)
            }
    
            // Only idents
    
            let p = Char {c: 'c'};
    
            let p2 = Char {c: 'x'};
    
            match parser_s!(p <~> p2).parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
            match parser_s!((p) <~> p2).parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
            match parser_s!(p <~> (p2)).parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
    
            let p = Char {c: 'c'};
    
            let p2 = Char {c: 'x'};
    
            match parser_s!((p) <~> (p2)).parse("cx") {
    
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
                Err(e) => panic!("{}", e)
            }
    
    
    
            // Combining idents and literals
    
            let p = Char {c: 'x'};
    
            match parser_s!('c' <~> p).parse("cx") {
    
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
    
                    assert_eq!(c2, 'x');
    
            let p = Char {c: 'c'};
    
            match parser_s!(p <~>'x').parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
                Err(e) => panic!("{}", e)
    
    
            let p = Char {c: 'c'};
    
            match parser_s!((p)<~>'x').parse("cx") {
    
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'x'};
    
            match parser_s!('c'<~>(p)).parse("cx") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
    
                    assert_eq!(c2, 'x');
                    Ok(())
                },
                Err(e) => panic!("{}", e)
            }
            
        }
    
        fn test_zip_recursive() -> Result<(), String>{
    
            match parser_s!(('c'<~>'x') <~> 'k').parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'k'};
    
            match parser_s!(('c'<~>'x') <~> p).parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
    
                Err(e) => panic!("{}", e)
            }
    
    
            match parser_s!('c'<~> ('x' <~> 'k')).parse("cxk") {
                Ok((c1, (c2, c3))) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'c'};
    
    
            match parser_s!(p <~> ('x' <~> 'k')).parse("cxk") {
                Ok((c1, (c2, c3))) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
            let p = Char {c: 'c'};
    
    
            match parser_s!(p <~> ('x' <~> ('k' <~> 'p'))).parse("cxkp") {
                Ok((c1, (c2, (c3, c4)))) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                    assert_eq!(c4, 'p');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            // Right associativity
    
            match parser_s!('c' <~> 'x' <~> ('k')).parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            match parser_s!('c' <~> 'x' <~> 'k').parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
                Err(e) => panic!("{}", e)
    
            let p = Char {c: 'c'};
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
    
            match parser_s!(p <~> 'x' <~> 'k').parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                },
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'x'};
    
            match parser_s!('c' <~> p <~> 'k').parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
            match parser_s!(p <~> p2 <~> 'k').parse("cxk") {
                Ok(((c1, c2), c3)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!('c' <~> ('x' <~> 'k') <~> 'r').parse("cxkr") {
                Ok(((c1, (c2, c3)), c4)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                    assert_eq!(c4, 'r');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(('c' <~> 'x') <~> 'k' <~> 'r').parse("cxkr") {
                Ok((((c1, c2),  c3), c4)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                    assert_eq!(c4, 'r');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            match parser_s!(('c' <~> 'x') <~> ('k' <~> 'r') <~> 'm').parse("cxkrm") {
                Ok((((c1, c2),  (c3, c4)), c5)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                    assert_eq!(c4, 'r');
                    assert_eq!(c5, 'm');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(('c' <~> 'x') <~> ('k' <~> 'r') <~> 'm').parse("cxkrm") {
                Ok((((c1, c2),  (c3, c4)), c5)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                    assert_eq!(c4, 'r');
                    assert_eq!(c5, 'm');
                },
                Err(e) => panic!("{}", e)
            }
    
            // Not fully covered, but essentially right associativity with idents
    
            let p = Char {c:'k'};
            match parser_s!(('c' <~> 'x') <~> p <~> 'm').parse("cxkm") {
                Ok((((c1, c2),  c3), c4)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'x');
                    assert_eq!(c3, 'k');
                    assert_eq!(c4, 'm');
                },
                Err(e) => panic!("{}", e)
            }
    
            Ok(())
    
    
    Carlos Valencia's avatar
    Carlos Valencia committed
        #[test]
    
        fn test_alternative_base() -> Result<(), String>{
    
            // Only literals
            match parser_s!('c'<|>'x').parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!(('c'<|>'x')).parse("x") {
                Ok(c1) => {
                    assert_eq!(c1, 'x');
                },
                Err(e) => panic!("{}", e)
            }
    
            // Only idents
    
    Carlos Valencia's avatar
    Carlos Valencia committed
            let p = Char {c: 'c'};
    
            let p2 = Char {c: 'x'};
    
            match parser_s!(p <|> p2).parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
            match parser_s!((p) <|> p2).parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
            match parser_s!(p <|> (p2)).parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
                Err(e) => panic!("{}", e)
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
    
            match parser_s!((p) <|> (p2)).parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            // Combining idents and literals
    
            let p = Char {c: 'x'};
    
            match parser_s!('k' <|> p).parse("x") {
                Ok(c1) => {
                    assert_eq!(c1, 'x');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'c'};
    
            match parser_s!(p <|>'x').parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'c'};
    
            match parser_s!((p)<|>'x').parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'x'};
    
            match parser_s!('c'<|>(p)).parse("cx") {
                Ok(c1) => {
                    assert_eq!(c1, 'c');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                    Ok(())
                },
                Err(e) => panic!("{}", e)
            }
            
        }
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
        #[test]
    
        fn test_alternative_recursive() -> Result<(), String>{
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
    
            match parser_s!(('c'<|>'x') <|> 'k').parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'k'};
    
            match parser_s!(('c'<|>'x') <|> p).parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!('c'<|> ('x' <|> 'k')).parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'c'};
    
            match parser_s!(p <|> ('x' <|> 'k')).parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'c'};
    
    
            match parser_s!(p <|> ('x' <|> ('k' <|> 'p'))).parse("cxkp") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
            // Right associativity
    
            match parser_s!('c' <|> 'x' <|> ('k')).parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
            match parser_s!('c' <|> 'x' <|> 'k').parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
            let p = Char {c: 'c'};
    
    
            match parser_s!(p <|> 'x' <|> 'k').parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'x'};
    
            match parser_s!('c' <|> p <|> 'k').parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = Char {c: 'c'};
            let p2 = Char {c: 'x'};
    
            match parser_s!(p <|> p2 <|> 'k').parse("cxk") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            match parser_s!('c' <|> ('x' <|> 'k') <|> 'r').parse("cxkr") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            match parser_s!(('c' <|> 'x') <|> 'k' <|> 'r').parse("cxkr") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
    
            match parser_s!(('c' <|> 'x') <|> ('k' <|> 'r') <|> 'm').parse("cxkrm") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            match parser_s!(('c' <|> 'x') <|> ('k' <|> 'r') <|> 'm').parse("cxkrm") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            // Not fully covered, but essentially right associativity with idents
    
            let p = Char {c:'k'};
            match parser_s!(('c' <|> 'x') <|> p <|> 'm').parse("cxkm") {
                Ok(c) => {
                    assert_eq!(c, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            Ok(())
    
        }
    
        #[test]
        fn test_alternative_zip() -> Result<(), String> {
    
            // Special case
            match parser_s!('a' <|> 'b' <~> 'c').parse("ac") {
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Ok((c1, c2)) => {
    
                    assert_eq!(c1, 'a');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                    assert_eq!(c2, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            let p = parser_s!('a' <~> 'c');
    
            match parser_s!(p <|> 'b' <~> 'c').parse("ac") {
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Ok((c1, c2)) => {
    
                    assert_eq!(c1, 'a');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                    assert_eq!(c2, 'c');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            let p = parser_s!('a' <~> 'c');
            let p2 = parser_s!('b');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
    
            match parser_s!(p <|> p2 <~> 'c').parse("bc") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = parser_s!('a' <~> 'c');
    
            match parser_s!(p <|> ('a' <|> 'b') <~> 'c').parse("bc") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
            let p = parser_s!('b');
    
            match parser_s!(('a' <~> 'b') <|> p <~> 'c').parse("bc") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'c');
                },
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                Err(e) => panic!("{}", e)
            }
    
    
    
            match parser_s!(('a' <~> 'b') <|> 'b' <~> 'c').parse("bc") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'c');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                },
                Err(e) => panic!("{}", e)
            }
    
    
    
    
            match parser_s!(('a' <~> 'b') <|> ('b' <|> 'k') <~> 'c').parse("bc") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'c');
    
    Carlos Valencia's avatar
    Carlos Valencia committed
                },
                Err(e) => panic!("{}", e)
            }
    
    Carlos Valencia's avatar
    Carlos Valencia committed
            Ok(())
        }
    
        
        #[test]
        fn test_zip_alternative() -> Result<(), String> {
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
    
            match parser_s!('a' <~> 'b' <|> 'c').parse("ab") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'b');
                },
                Err(e) => panic!("{}", e)
            }
    
    Carlos Valencia's avatar
    Carlos Valencia committed
    
    
            let p = parser_s!('c' <~> 'd');
            match parser_s!('a' <~> 'b' <|> p).parse("ab") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'b');
                },
                Err(e) => panic!("{}", e)
    
    Carlos Valencia's avatar
    Carlos Valencia committed
            }
    
    
            let p = parser_s!('a');
            let p2 = parser_s!('c' <~> 'd');
            match parser_s!(p <~> 'b' <|> p2).parse("cd") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'c');
                    assert_eq!(c2, 'd');
                },
                Err(e) => panic!("{}", e)
    
    Carlos Valencia's avatar
    Carlos Valencia committed
            }
    
    
            let p = parser_s!('b');
            let p2 = parser_s!('c' <~> 'd');
            match parser_s!('a' <~> p <|> p2).parse("ab") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'b');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = parser_s!('a');
            let p2 = parser_s!('b');
            let p3 = parser_s!('c' <~> 'd');
            match parser_s!(p <~> p2 <|> p3).parse("ab") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'b');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = parser_s!('c' <~> 'd');
            match parser_s!('a' <~> ('a' <|> 'b') <|> p).parse("ab") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'b');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p = parser_s!('c' <~> 'd');
            match parser_s!(('a' <|> 'b') <~> 'a' <|> p).parse("ba") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'a');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p1 = parser_s!('a');
            let p2 = parser_s!('c' <~> 'd');
            match parser_s!(p1 <~> ('a' <|> 'b') <|> p2).parse("aa") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'a');
                },
                Err(e) => panic!("{}", e)
            }
    
            let p1 = parser_s!('a');
            let p2 = parser_s!('c' <~> 'd');
            match parser_s!(('a' <|> 'b') <~> p1 <|> p2).parse("ba") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'b');
                    assert_eq!(c2, 'a');
                },
                Err(e) => panic!("{}", e)
            }
    
    
            let p3 = parser_s!('c' <~> 'd');
            match parser_s!(('a' <|> 'b') <~> ('b' <|> 'a') <|> p3).parse("ab") {
                Ok((c1, c2)) => {
                    assert_eq!(c1, 'a');
                    assert_eq!(c2, 'b');
                },
                Err(e) => panic!("{}", e)
            }
    
    
    Carlos Valencia's avatar
    Carlos Valencia committed
            Ok(())
        }
    
        
    
        // #[test]
        // fn test_left() -> Result<(), String>{
        //     let p = Char {c: 'c'};
        //     let p2 = Char {c: 'k'};
        //     let p3 = Char {c: 'l'};
    
        //     match parser_s!('c'<*'x').parse("cx") {
        //         Ok(c) => assert_eq!(c, 'c'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(p<*p2).parse("ck") {
        //         Ok(c) => assert_eq!(c, 'c'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!('c' <* 'm').parse("cl") {
        //         Ok(_) => panic!("Didnt fail at m"),
        //         Err(_e) => ()
        //     }
    
        //     // match parser_s!(('c' <* ('a' <* 'r'))).parse("car") {
        //     //     Ok(c) => assert_eq!(c, 'c'),
        //     //     Err(e) => panic!("{}", e)
        //     // }
    
        //     match parser_s!(p3<*'x').parse("lx") {
        //         Ok(c) => {
        //             assert_eq!(c, 'l');
        //             Ok(())
        //         },
        //         Err(e) => panic!("{}", e)
        //     }
            
        // }
    
        // #[test]
        // fn test_right() -> Result<(), String>{
        //     let p = Char {c: 'c'};
        //     let p2 = Char {c: 'k'};
        //     let p3 = Char {c: 'l'};
    
        //     match parser_s!('c'*>'x').parse("cx") {
        //         Ok(c) => assert_eq!(c, 'x'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(p*>p2).parse("ck") {
        //         Ok(c) => assert_eq!(c, 'k'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!('c' *> 'm').parse("cl") {
        //         Ok(_) => panic!("Didnt fail at m"),
        //         Err(_e) => ()
        //     }
    
        //     // let p = Char {c: 'a'};
        //     // match parser_s!('c' *> p *> 'r').parse("car") {
        //     //     Ok(c) => assert_eq!(c, 'r'),
        //     //     Err(e) => panic!("{}", e)
        //     // }
    
        //     // let p = Char {c: 'c'};
        //     // match parser_s!((p *> 'a' *> 'r')).parse("car") {
        //     //     Ok(c) => assert_eq!(c, 'r'),
        //     //     Err(e) => panic!("{}", e)
        //     // }
    
        //     match parser_s!(p3*>'x').parse("lx") {
        //         Ok(c) => {
        //             assert_eq!(c, 'x');
        //             Ok(())
        //         },
        //         Err(e) => panic!("{}", e)
        //     }
            
        // }
    
        // #[test]
        // fn test_recursive() -> Result<(), String> {
    
        //     match parser_s!(('a' *> 'b') <|> 'c').parse("ab") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(('a' *> 'b') <|> 'c').parse("cb") {
        //         Ok(c) => assert_eq!(c, 'c'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     let p = Char {c: 'c'};
        //     match parser_s!(('a' *> 'b') <|> p).parse("ab") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     let p = Char {c: 'c'};
        //     match parser_s!(p *> 'b' <|> 'k').parse("cb") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(('a' <|> 'b') <|> 'c').parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(('a' <|> 'b') <|> 'c').parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!('a' <|> 'b' <|> 'c').parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!('a' <|> 'b' <|> ('c' <|> 'c')).parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     let p = Char {c: 'a'};
        //     match parser_s!(p <|> 'b' <|> ('c' <|> 'c') <|> 'l').parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     let p = Char {c: 'b'};
        //     match parser_s!('a' <|> p <|> ('c' <|> 'c')).parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     let p1 = Char {c: 'a'};
        //     let p2 = Char {c: 'b'};
        //     match parser_s!(p1 <|> p2 <|> ('c' <|> 'c')).parse("b") {
        //         Ok(c) => assert_eq!(c, 'b'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(('a' <~> 'b') <|> ('c' <~> 'c')).parse("cc") {
        //         Ok((c1, c2)) => {
        //             assert_eq!(c1, 'c');
        //             assert_eq!(c2, 'c');
        //         },
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!('a' <~> 'b' <|> ('c' <~> 'c')).parse("cc") {
        //         Ok((c1, c2)) => {
        //             assert_eq!(c1, 'c');
        //             assert_eq!(c2, 'c');
        //         },
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(('a' *> 'b') *> 'c').parse("abc") {
        //         Ok(c) => assert_eq!(c, 'c'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     let p = Char {c: 'a'};
        //     match parser_s!(p *> ('b' *> 'c')).parse("abc") {
        //         Ok(c) => assert_eq!(c, 'c'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!(('a' <* 'b') <* 'c').parse("abc") {
        //         Ok(c) => assert_eq!(c, 'a'),
        //         Err(e) => panic!("{}", e)
        //     }
    
        //     match parser_s!('a' <* ('b' <* 'c')).parse("abc") {
        //         Ok(c) => assert_eq!(c, 'a'),
        //         Err(e) => panic!("{}", e)
        //     }