foliage-rs/src/parse/literals.rs

181 lines
3.8 KiB
Rust

use nom::
{
IResult,
branch::alt,
bytes::complete::tag,
character::complete::digit1,
combinator::{map, map_res, opt, recognize},
sequence::{pair, terminated},
};
use super::word_boundary;
fn true_(i: &str) -> IResult<&str, bool>
{
map
(
terminated
(
tag("true"),
word_boundary,
),
|_| true,
)(i)
}
fn false_(i: &str) -> IResult<&str, bool>
{
map
(
terminated
(
tag("false"),
word_boundary,
),
|_| false,
)(i)
}
pub fn boolean(i: &str) -> IResult<&str, bool>
{
alt
((
true_,
false_,
))(i)
}
pub fn integer(i: &str) -> IResult<&str, i32>
{
map_res
(
recognize
(
terminated
(
pair
(
opt
(
alt
((
tag("-"),
tag("+"),
))
),
digit1,
),
word_boundary,
)
),
std::str::FromStr::from_str,
)(i)
}
fn infimum(i: &str) -> IResult<&str, crate::SpecialInteger>
{
map
(
terminated
(
tag("#inf"),
word_boundary,
),
|_| crate::SpecialInteger::Infimum,
)(i)
}
fn supremum(i: &str) -> IResult<&str, crate::SpecialInteger>
{
map
(
terminated
(
tag("#sup"),
word_boundary,
),
|_| crate::SpecialInteger::Supremum,
)(i)
}
pub fn special_integer(i: &str) -> IResult<&str, crate::SpecialInteger>
{
alt
((
infimum,
supremum,
))(i)
}
#[cfg(test)]
mod tests
{
use crate::SpecialInteger;
use crate::parse::*;
#[test]
fn parse_boolean()
{
assert_eq!(boolean("true"), Ok(("", true)));
assert_eq!(boolean("false"), Ok(("", false)));
assert_eq!(boolean("true false"), Ok((" false", true)));
assert_eq!(boolean("false true"), Ok((" true", false)));
assert_eq!(boolean("true,"), Ok((",", true)));
assert_eq!(boolean("false,"), Ok((",", false)));
assert!(boolean("truefalse").is_err());
assert!(boolean("falsetrue").is_err());
assert!(boolean("truea").is_err());
assert!(boolean("falsea").is_err());
assert!(boolean("a").is_err());
assert!(boolean("-").is_err());
assert!(boolean(" ").is_err());
}
#[test]
fn parse_integer()
{
assert_eq!(integer("0"), Ok(("", 0)));
assert_eq!(integer("10000"), Ok(("", 10000)));
assert_eq!(integer("+10000"), Ok(("", 10000)));
assert_eq!(integer("-10000"), Ok(("", -10000)));
assert_eq!(integer("0 42"), Ok((" 42", 0)));
assert_eq!(integer("10000 42"), Ok((" 42", 10000)));
assert_eq!(integer("+10000 42"), Ok((" 42", 10000)));
assert_eq!(integer("-10000 42"), Ok((" 42", -10000)));
assert_eq!(integer("10000,"), Ok((",", 10000)));
assert_eq!(integer("+10000,"), Ok((",", 10000)));
assert_eq!(integer("-10000,"), Ok((",", -10000)));
assert!(integer("10000a").is_err());
assert!(integer("+10000a").is_err());
assert!(integer("-10000a").is_err());
assert!(integer("1.5").is_err());
assert!(integer("a").is_err());
assert!(integer("-").is_err());
assert!(integer(" ").is_err());
}
#[test]
fn parse_special_integer()
{
assert_eq!(special_integer("#inf"), Ok(("", SpecialInteger::Infimum)));
assert_eq!(special_integer("#sup"), Ok(("", SpecialInteger::Supremum)));
assert_eq!(special_integer("#inf #sup"), Ok((" #sup", SpecialInteger::Infimum)));
assert_eq!(special_integer("#sup #inf"), Ok((" #inf", SpecialInteger::Supremum)));
assert_eq!(special_integer("#inf,"), Ok((",", SpecialInteger::Infimum)));
assert_eq!(special_integer("#sup,"), Ok((",", SpecialInteger::Supremum)));
assert!(special_integer("#inf0").is_err());
assert!(special_integer("#sup0").is_err());
assert!(special_integer("#infimum").is_err());
assert!(special_integer("#supremum").is_err());
assert!(special_integer("inf").is_err());
assert!(special_integer("sup").is_err());
assert!(special_integer("0").is_err());
assert!(special_integer("10000").is_err());
assert!(special_integer("-10000").is_err());
assert!(special_integer("-").is_err());
assert!(special_integer("+").is_err());
assert!(special_integer("a").is_err());
assert!(special_integer(" ").is_err());
}
}