Propogate errors from parsing with try_parse!()

This commit is contained in:
Frederik Palmø 2021-10-24 16:32:11 +02:00
parent 87903ce905
commit a94f74dc78
3 changed files with 21 additions and 14 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "eyes" name = "eyes"
version = "1.0.1" version = "1.1"
edition = "2018" edition = "2018"
description = "A simpler way to parse using human-readable templates" description = "A simpler way to parse using human-readable templates"
license="BSD-3-Clause" license="BSD-3-Clause"

View file

@ -3,7 +3,7 @@ pub struct Parser<'a> {
} }
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
pub fn new(input: &'a str, template: &'a str) -> Self { pub fn new(input: &'a str, template: &'a str) -> Option<Self> {
let patterns = template let patterns = template
.split("{}") .split("{}")
.filter(|pat| pat != &"") .filter(|pat| pat != &"")
@ -11,14 +11,14 @@ impl<'a> Parser<'a> {
let mut captures = vec![input]; let mut captures = vec![input];
for (i, pat) in patterns.iter().enumerate() { for (i, pat) in patterns.iter().enumerate() {
let last = captures.pop().unwrap(); let last = captures.pop()?;
let (mut left, mut right) = last.split_once(pat).unwrap(); let (mut left, mut right) = last.split_once(pat)?;
// if the right side of the split doesn't contain the pattern, // if the right side of the split doesn't contain the pattern,
// we don't have to check if we can expand the match // we don't have to check if we can expand the match
if right.contains(pat) { if right.contains(pat) {
let mut pattern_index = right.find(pat).unwrap() + left.len(); let mut pattern_index = right.find(pat)? + left.len();
let next_pattern_index = right.find(patterns[i + 1]).unwrap() + left.len(); let next_pattern_index = right.find(patterns[i + 1])? + left.len();
while next_pattern_index > pattern_index { while next_pattern_index > pattern_index {
let (left_side, _) = input.split_at(pattern_index + 1); let (left_side, _) = input.split_at(pattern_index + 1);
@ -36,7 +36,7 @@ impl<'a> Parser<'a> {
captures.push(right); captures.push(right);
} }
Self { captures } Some(Self { captures })
} }
pub fn captures(&self) -> Vec<&'a str> { pub fn captures(&self) -> Vec<&'a str> {
@ -48,7 +48,7 @@ impl<'a> Parser<'a> {
macro_rules! parse { macro_rules! parse {
($input: expr, $pattern: tt, $($type:ty),*) => { ($input: expr, $pattern: tt, $($type:ty),*) => {
{ {
let parser = $crate::Parser::new($input, $pattern); let parser = $crate::Parser::new($input, $pattern).unwrap();
let captures = parser.captures(); let captures = parser.captures();
let mut iter = captures.iter(); let mut iter = captures.iter();
@ -61,11 +61,16 @@ macro_rules! parse {
macro_rules! try_parse { macro_rules! try_parse {
($input: expr, $pattern: tt, $($type:ty),*) => { ($input: expr, $pattern: tt, $($type:ty),*) => {
{ {
let parser = $crate::Parser::new($input, $pattern); if let Some(parser) = $crate::Parser::new($input, $pattern) {
let captures = parser.captures(); let captures = parser.captures();
let mut iter = captures.iter(); let mut iter = captures.iter();
($(iter.next().unwrap().parse::<$type>()),*) Some(($(iter.next().unwrap().parse::<$type>()),*))
} else {
None
}
} }
}; };
} }
@ -102,7 +107,8 @@ mod tests {
println!("input: '{}'", input); println!("input: '{}'", input);
println!("pattern: '{}'", template); println!("pattern: '{}'", template);
let (op, x1, y1, x2, y2) = try_parse!(input, template, String, usize, usize, usize, usize); let (op, x1, y1, x2, y2) =
try_parse!(input, template, String, usize, usize, usize, usize).unwrap();
println!("op: {:?}", op); println!("op: {:?}", op);
println!("p1: {:?}", (&x1, &y1)); println!("p1: {:?}", (&x1, &y1));

View file

@ -7,7 +7,8 @@ fn main() {
println!("input: '{}'", input); println!("input: '{}'", input);
println!("pattern: '{}'", template); println!("pattern: '{}'", template);
let (op, x1, y1, x2, y2) = try_parse!(input, template, String, usize, usize, usize, usize); let (op, x1, y1, x2, y2) =
try_parse!(input, template, String, usize, usize, usize, usize).unwrap();
println!("op: {:?}", op); println!("op: {:?}", op);
println!("p1: {:?}", (x1, y1)); println!("p1: {:?}", (x1, y1));