From 97c0e506542caf7291300ee104b7b0d6735865c6 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Wed, 16 Mar 2022 23:19:50 +0000 Subject: [PATCH] Parse numbers as either integers or decimals --- lib/src/sql/number.rs | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/src/sql/number.rs b/lib/src/sql/number.rs index 4556c662..c7e44ba8 100644 --- a/lib/src/sql/number.rs +++ b/lib/src/sql/number.rs @@ -1,4 +1,5 @@ use crate::sql::comment::comment; +use crate::sql::error::Error::ParserError; use crate::sql::error::IResult; use crate::sql::operator::{assigner, operator}; use dec::prelude::FromPrimitive; @@ -6,12 +7,14 @@ use dec::prelude::ToPrimitive; use dec::Decimal; use dec::MathematicalOps; use nom::branch::alt; -use nom::bytes::complete::tag; +use nom::character::complete::char; +use nom::character::complete::digit1; use nom::character::complete::multispace1; use nom::combinator::eof; use nom::combinator::map; use nom::combinator::peek; use nom::number::complete::recognize_float; +use nom::Err::Error; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::fmt; @@ -499,17 +502,41 @@ impl<'a> Product<&'a Self> for Number { } pub fn number(i: &str) -> IResult<&str, Number> { + alt((integer, decimal))(i) +} + +fn integer(i: &str) -> IResult<&str, Number> { + let (i, v) = digit1(i)?; + let (i, _) = peek(alt(( + map(multispace1, |_| ()), + map(operator, |_| ()), + map(assigner, |_| ()), + map(comment, |_| ()), + map(char(')'), |_| ()), + map(char(']'), |_| ()), + map(char('}'), |_| ()), + map(char(';'), |_| ()), + map(char(','), |_| ()), + map(eof, |_| ()), + )))(i)?; + match v.parse::() { + Ok(v) => Ok((i, Number::from(v))), + _ => Err(Error(ParserError(i))), + } +} + +fn decimal(i: &str) -> IResult<&str, Number> { let (i, v) = recognize_float(i)?; let (i, _) = peek(alt(( map(multispace1, |_| ()), map(operator, |_| ()), map(assigner, |_| ()), map(comment, |_| ()), - map(tag(")"), |_| ()), - map(tag("]"), |_| ()), - map(tag("}"), |_| ()), - map(tag(";"), |_| ()), - map(tag(","), |_| ()), + map(char(')'), |_| ()), + map(char(']'), |_| ()), + map(char('}'), |_| ()), + map(char(';'), |_| ()), + map(char(','), |_| ()), map(eof, |_| ()), )))(i)?; Ok((i, Number::from(v)))