From 04e85ead3539fbbcc0f091601ac38c7e2f39b2e5 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Thu, 27 Jun 2019 15:54:37 +0200 Subject: port to nom 5 --- Cargo.toml | 2 +- src/error.rs | 2 +- src/path/mod.rs | 2 +- src/path/parser.rs | 91 +++++++++++++++++++++++++++++------------------------- 4 files changed, 52 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d6360fc..f552505 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ ini = ["rust-ini"] [dependencies] lazy_static = "1.0" serde = "1.0.8" -nom = "4.0.0" +nom = "5.0.0" toml = { version = "0.5", optional = true } serde_json = { version = "1.0.2", optional = true } diff --git a/src/error.rs b/src/error.rs index e305750..d7beeaf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -41,7 +41,7 @@ pub enum ConfigError { NotFound(String), /// Configuration path could not be parsed. - PathParse(nom::ErrorKind), + PathParse(nom::error::ErrorKind), /// Configuration could not be parsed from file. FileParse { diff --git a/src/path/mod.rs b/src/path/mod.rs index 7fe6e44..f63deee 100644 --- a/src/path/mod.rs +++ b/src/path/mod.rs @@ -1,5 +1,5 @@ use error::*; -use nom::ErrorKind; +use nom::error::ErrorKind; use std::collections::HashMap; use std::str::FromStr; use value::{Value, ValueKind}; diff --git a/src/path/parser.rs b/src/path/parser.rs index a1660ca..d783f3e 100644 --- a/src/path/parser.rs +++ b/src/path/parser.rs @@ -1,53 +1,53 @@ use super::Expression; -use nom::types::CompleteStr; -use nom::{digit, ErrorKind, IResult}; +use nom::{ + IResult, Err, + error::ErrorKind, + bytes::complete::{is_a, tag}, + character::complete::{char, digit1, space0}, + sequence::{delimited, pair, preceded}, + branch::alt, + combinator::{map, map_res, opt, recognize}, +}; use std::str::{from_utf8, FromStr}; -named!(raw_ident, - map!(is_a!( +fn raw_ident(i: &str) -> IResult<&str, String> { + map(is_a( "abcdefghijklmnopqrstuvwxyz \ ABCDEFGHIJKLMNOPQRSTUVWXYZ \ 0123456789 \ _-" - ), |s: CompleteStr| { - s.to_string() - }) -); - -named!(integer, - map_res!( - ws!(digit), - |s: CompleteStr| { - s.parse() - } - ) -); - -named!(ident, map!(raw_ident, Expression::Identifier)); - -#[allow(cyclomatic_complexity)] -fn postfix(expr: Expression) -> Box IResult> { - Box::new(move |i: CompleteStr| { - alt!( - i, - do_parse!(tag!(".") >> id: raw_ident >> (Expression::Child(Box::new(expr.clone()), id))) - | delimited!( - char!('['), - do_parse!( - negative: opt!(tag!("-")) >> num: integer - >> (Expression::Subscript( - Box::new(expr.clone()), - num * (if negative.is_none() { 1 } else { -1 }), - )) - ), - char!(']') - ) - ) - }) + ), |s:&str| s.to_string())(i) +} + +fn integer(i: &str) -> IResult<&str, isize> { + map_res( + delimited( + space0, + recognize(pair(opt(tag("-")), digit1)), + space0 + ), + FromStr::from_str + )(i) +} + +fn ident(i: &str) -> IResult<&str, Expression> { + map(raw_ident, Expression::Identifier)(i) +} + +fn postfix<'a>(expr: Expression) -> impl Fn(&'a str) -> IResult<&'a str, Expression> { + let e2 = expr.clone(); + let child = map(preceded(tag("."), raw_ident), move |id| Expression::Child(Box::new(expr.clone()), id)); + + let subscript = map(delimited(char('['), integer, char(']')), move |num| Expression::Subscript(Box::new(e2.clone()), num)); + + alt(( + child, + subscript + )) } pub fn from_str(input: &str) -> Result { - match ident(CompleteStr(input)) { + match ident(input) { Ok((mut rem, mut expr)) => { while !rem.is_empty() { match postfix(expr)(rem) { @@ -58,7 +58,7 @@ pub fn from_str(input: &str) -> Result { // Forward Incomplete and Error result => { - return result.map(|(_, o)| o).map_err(|e| e.into_error_kind()); + return result.map(|(_, o)| o).map_err(to_error_kind); } } } @@ -67,10 +67,17 @@ pub fn from_str(input: &str) -> Result { } // Forward Incomplete and Error - result => result.map(|(_, o)| o).map_err(|e| e.into_error_kind()), + result => result.map(|(_, o)| o).map_err(to_error_kind), } } +pub fn to_error_kind(e: Err<(&str, ErrorKind)>) -> ErrorKind { + match e { + Err::Incomplete(_) => ErrorKind::Complete, + Err::Failure((_, e)) | Err::Error((_, e)) => e, + } +} + #[cfg(test)] mod test { use super::Expression::*; -- cgit v1.2.3