Parse numbers as either integers or decimals
This commit is contained in:
parent
636eee4a25
commit
97c0e50654
1 changed files with 33 additions and 6 deletions
|
@ -1,4 +1,5 @@
|
||||||
use crate::sql::comment::comment;
|
use crate::sql::comment::comment;
|
||||||
|
use crate::sql::error::Error::ParserError;
|
||||||
use crate::sql::error::IResult;
|
use crate::sql::error::IResult;
|
||||||
use crate::sql::operator::{assigner, operator};
|
use crate::sql::operator::{assigner, operator};
|
||||||
use dec::prelude::FromPrimitive;
|
use dec::prelude::FromPrimitive;
|
||||||
|
@ -6,12 +7,14 @@ use dec::prelude::ToPrimitive;
|
||||||
use dec::Decimal;
|
use dec::Decimal;
|
||||||
use dec::MathematicalOps;
|
use dec::MathematicalOps;
|
||||||
use nom::branch::alt;
|
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::character::complete::multispace1;
|
||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::combinator::peek;
|
use nom::combinator::peek;
|
||||||
use nom::number::complete::recognize_float;
|
use nom::number::complete::recognize_float;
|
||||||
|
use nom::Err::Error;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -499,17 +502,41 @@ impl<'a> Product<&'a Self> for Number {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn number(i: &str) -> IResult<&str, 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::<i64>() {
|
||||||
|
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, v) = recognize_float(i)?;
|
||||||
let (i, _) = peek(alt((
|
let (i, _) = peek(alt((
|
||||||
map(multispace1, |_| ()),
|
map(multispace1, |_| ()),
|
||||||
map(operator, |_| ()),
|
map(operator, |_| ()),
|
||||||
map(assigner, |_| ()),
|
map(assigner, |_| ()),
|
||||||
map(comment, |_| ()),
|
map(comment, |_| ()),
|
||||||
map(tag(")"), |_| ()),
|
map(char(')'), |_| ()),
|
||||||
map(tag("]"), |_| ()),
|
map(char(']'), |_| ()),
|
||||||
map(tag("}"), |_| ()),
|
map(char('}'), |_| ()),
|
||||||
map(tag(";"), |_| ()),
|
map(char(';'), |_| ()),
|
||||||
map(tag(","), |_| ()),
|
map(char(','), |_| ()),
|
||||||
map(eof, |_| ()),
|
map(eof, |_| ()),
|
||||||
)))(i)?;
|
)))(i)?;
|
||||||
Ok((i, Number::from(v)))
|
Ok((i, Number::from(v)))
|
||||||
|
|
Loading…
Reference in a new issue