schala/src/combinators/mod.rs

67 lines
1.7 KiB
Rust

mod map;
mod optional;
mod repeated;
mod separated_by;
pub use map::map;
pub use optional::optional;
pub use repeated::repeated;
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::Parser;
use crate::primitives::literal;
#[test]
fn test_map() {
let lit_a = literal("a");
let output = lit_a.map(|s| s.to_uppercase()).parse("a yolo");
assert_eq!(output.unwrap(), ("A".to_string(), " yolo"));
}
#[test]
fn test_one_or_more() {
let p = repeated(literal("bongo ")).at_least(1);
let input = "bongo bongo bongo bongo bongo ";
let (output, rest) = p.parse(input).unwrap();
assert_eq!(rest, "");
assert_eq!(output.len(), 5);
let (output, rest) = p.parse("bongo ecks").unwrap();
assert_eq!(output.len(), 1);
assert_eq!(rest, "ecks");
}
#[test]
fn test_separated_by() {
let p = repeated(literal("garb").to(20))
.separated_by(repeated(literal(" ")).at_least(1), false);
assert_eq!(
p.parse("garb garb garb garb").unwrap(),
(vec![20, 20, 20, 20], "")
);
assert!(p.parse("garb garb garb garb ").is_err());
let p =
repeated(literal("garb").to(20)).separated_by(repeated(literal(" ")).at_least(1), true);
assert_eq!(
p.parse("garb garb garb garb").unwrap(),
(vec![20, 20, 20, 20], "")
);
assert_eq!(
p.parse("garb garb garb garb ").unwrap(),
(vec![20, 20, 20, 20], "")
);
assert_eq!(
p.parse("garb garb garb garb q").unwrap(),
(vec![20, 20, 20, 20], "q")
);
}
}