use winnow::{
ascii::multispace1,
combinator::{alt, delimited, opt, preceded, repeat, separated},
error::{FromExternalError, ParserError},
token::{take_till, take_while},
PResult, Parser,
};
use crate::{
comments::space_or_comment0,
primitive_literals::{
bool_literal, float_literal, identifier, int_literal, var_par_identifier,
},
};
pub type Annotations = Vec<Annotation>;
pub fn annotations<'a, E>(input: &mut &'a str) -> PResult<Annotations, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
repeat(0.., annotation1).parse_next(input)
}
fn annotation1<'a, E>(input: &mut &'a str) -> PResult<Annotation, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
"::".parse_next(input)?;
space_or_comment0(input)?;
annotation(input)
}
#[derive(PartialEq, Clone, Debug)]
pub struct Annotation {
pub id: String,
pub expressions: Vec<AnnExpr>,
}
fn annotation<'a, E>(input: &mut &'a str) -> PResult<Annotation, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
let id = identifier(input)?;
let we = opt('(').parse_next(input)?;
if we.is_some() {
let expressions_what = separated(1.., ann_expr, ',').parse_next(input)?;
')'.parse_next(input)?;
Ok(Annotation {
id,
expressions: expressions_what,
})
} else {
space_or_comment0(input)?;
Ok(Annotation {
id,
expressions: vec![],
})
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum AnnExpr {
Annotations(Annotations),
String(String),
Expr(Expr),
}
fn ann_expr<'a, E>(input: &mut &'a str) -> PResult<AnnExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
alt((ann_non_array_expr, ae_annotations)).parse_next(input)
}
fn ae_annotations<'a, E>(input: &mut &'a str) -> PResult<AnnExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let res = separated(1.., annotation, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(AnnExpr::Annotations(res))
}
fn ann_non_array_expr<'a, E>(input: &mut &'a str) -> PResult<AnnExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
alt((ae_expr, string_lit)).parse_next(input)
}
fn ae_expr<'a, E>(input: &mut &'a str) -> PResult<AnnExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
let expr = expr(input)?;
Ok(AnnExpr::Expr(expr))
}
fn parse_unicode<'a, E>(input: &mut &'a str) -> PResult<char, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let parse_hex = take_while(1..6, |c: char| c.is_ascii_hexdigit());
let parse_delimited_hex = preceded('u', delimited('{', parse_hex, '}'));
if let Some(hex) = opt(parse_delimited_hex).parse_next(input)? {
if let Ok(u) = u32::from_str_radix(hex, 16) {
if let Some(x) = std::char::from_u32(u) {
Ok(x)
} else {
Err(ParserError::from_error_kind(
input,
winnow::error::ErrorKind::Assert,
))
}
} else {
Err(ParserError::from_error_kind(
input,
winnow::error::ErrorKind::Assert,
))
}
} else {
Err(ParserError::from_error_kind(
input,
winnow::error::ErrorKind::Assert,
))
}
}
fn parse_escaped_char<'a, E>(input: &mut &'a str) -> PResult<StringFragment<'a>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let c = preceded(
'\\',
alt((
parse_unicode,
'n'.value('\n'),
'r'.value('\r'),
't'.value('\t'),
'b'.value('\u{08}'),
'f'.value('\u{0C}'),
'\\',
'/',
'"',
)),
)
.parse_next(input)?;
Ok(StringFragment::EscapedChar(c))
}
fn parse_escaped_whitespace<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> PResult<StringFragment<'a>, E> {
preceded('\\', multispace1).parse_next(input)?;
Ok(StringFragment::EscapedWS)
}
fn parse_literal<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> PResult<StringFragment<'a>, E> {
let c = take_till(1.., ['\"', '\\']).parse_next(input)?;
Ok(StringFragment::Literal(c))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum StringFragment<'a> {
Literal(&'a str),
EscapedChar(char),
EscapedWS,
}
fn parse_fragment<'a, E>(input: &mut &'a str) -> PResult<StringFragment<'a>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
alt((
parse_literal,
parse_escaped_char,
parse_escaped_whitespace.value(StringFragment::EscapedWS),
))
.parse_next(input)
}
pub fn string_lit<'a, E>(input: &mut &'a str) -> PResult<AnnExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let build_string = repeat(0.., parse_fragment).fold(String::new, |mut string, fragment| {
match fragment {
StringFragment::Literal(s) => string.push_str(s),
StringFragment::EscapedChar(c) => string.push(c),
StringFragment::EscapedWS => {}
}
string
});
let string = delimited('"', build_string, '"').parse_next(input)?;
Ok(AnnExpr::String(string))
}
#[test]
fn test_string_lit() {
use winnow::error::ContextError;
let mut input = "\"bla\"";
assert_eq!(
string_lit::<ContextError>(&mut input),
Ok(AnnExpr::String("bla".to_string()))
);
}
#[test]
fn test_string_lit_escaped_characters() {
use winnow::error::ContextError;
let mut input = r#""escaped\"characters\ntest\u{0021}\u{01c3}""#;
assert_eq!(
string_lit::<ContextError>(&mut input),
Ok(AnnExpr::String("escaped\"characters\ntest!ǃ".to_string()))
);
}
#[derive(PartialEq, Clone, Debug)]
pub enum BoolExpr {
Bool(bool),
VarParIdentifier(String),
}
pub fn bool_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<BoolExpr, E> {
alt((be_bool_literal, be_var_par_identifier)).parse_next(input)
}
#[test]
fn test_bool_expr() {
use winnow::error::ContextError;
let mut input = "true);";
assert_eq!(
bool_expr::<ContextError>(&mut input),
Ok(BoolExpr::Bool(true))
);
}
fn be_bool_literal<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<BoolExpr, E> {
let expr = bool_literal(input)?;
Ok(BoolExpr::Bool(expr))
}
#[test]
fn test_bool_literal() {
use winnow::error::ContextError;
let mut input = "true);";
assert_eq!(
be_bool_literal::<ContextError>(&mut input),
Ok(BoolExpr::Bool(true))
);
assert_eq!(input, ");");
}
fn be_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<BoolExpr, E> {
let id = var_par_identifier(input)?;
Ok(BoolExpr::VarParIdentifier(id))
}
impl TryFrom<Expr> for BoolExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::Bool(value) => Ok(Self::Bool(value)),
_ => Err(()),
}
}
}
impl From<BoolExpr> for Expr {
fn from(expr: BoolExpr) -> Self {
match expr {
BoolExpr::Bool(value) => Self::Bool(value),
BoolExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum IntExpr {
Int(i128),
VarParIdentifier(String),
}
pub fn int_expr<'a, E>(input: &mut &'a str) -> PResult<IntExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
space_or_comment0(input)?;
let expr = alt((ie_int_literal, ie_var_par_identifier)).parse_next(input)?;
Ok(expr)
}
fn ie_int_literal<'a, E>(input: &mut &'a str) -> PResult<IntExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let expr = int_literal(input)?;
Ok(IntExpr::Int(expr))
}
fn ie_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<IntExpr, E> {
let id = var_par_identifier(input)?;
Ok(IntExpr::VarParIdentifier(id))
}
impl TryFrom<Expr> for IntExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::Int(value) => Ok(Self::Int(value)),
_ => Err(()),
}
}
}
impl From<IntExpr> for Expr {
fn from(expr: IntExpr) -> Self {
match expr {
IntExpr::Int(value) => Self::Int(value),
IntExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum FloatExpr {
Float(f64),
VarParIdentifier(String),
}
pub fn float_expr<'a, E>(input: &mut &'a str) -> PResult<FloatExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
alt((fe_float_literal, fe_var_par_identifier)).parse_next(input)
}
fn fe_float_literal<'a, E>(input: &mut &'a str) -> PResult<FloatExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
let expr = float_literal(input)?;
Ok(FloatExpr::Float(expr))
}
fn fe_var_par_identifier<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> PResult<FloatExpr, E> {
let id = var_par_identifier(input)?;
Ok(FloatExpr::VarParIdentifier(id))
}
impl TryFrom<Expr> for FloatExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::Float(value) => Ok(Self::Float(value)),
_ => Err(()),
}
}
}
impl From<FloatExpr> for Expr {
fn from(expr: FloatExpr) -> Self {
match expr {
FloatExpr::Float(value) => Self::Float(value),
FloatExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum SetExpr {
Set(SetLiteralExpr),
VarParIdentifier(String),
}
pub fn set_expr<'a, E>(input: &mut &'a str) -> PResult<SetExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
alt((se_set_literal_expr, se_var_par_identifier)).parse_next(input)
}
fn se_set_literal_expr<'a, E>(input: &mut &'a str) -> PResult<SetExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
let sl = set_literal_expr(input)?;
Ok(SetExpr::Set(sl))
}
fn se_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<SetExpr, E> {
let id = var_par_identifier(input)?;
Ok(SetExpr::VarParIdentifier(id))
}
impl TryFrom<Expr> for SetExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::Set(value) => Ok(Self::Set(value)),
_ => Err(()),
}
}
}
impl From<SetExpr> for Expr {
fn from(expr: SetExpr) -> Self {
match expr {
SetExpr::Set(value) => Self::Set(value),
SetExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum Expr {
VarParIdentifier(String),
Bool(bool),
Int(i128),
Float(f64),
Set(SetLiteralExpr),
ArrayOfBool(Vec<BoolExpr>),
ArrayOfInt(Vec<IntExpr>),
ArrayOfFloat(Vec<FloatExpr>),
ArrayOfSet(Vec<SetExpr>),
}
pub fn expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
space_or_comment0(input)?;
let expr = alt((
e_var_par_identifier,
e_bool_expr,
e_set_expr,
e_float_expr,
e_int_expr,
e_array_of_bool_expr,
e_array_of_int_expr,
e_array_of_float_expr,
e_array_of_set_expr,
))
.parse_next(input)?;
Ok(expr)
}
#[test]
fn test_expr() {
use winnow::error::ContextError;
let mut input = "1..2";
assert_eq!(
expr::<ContextError>(&mut input),
Ok(Expr::Set(SetLiteralExpr::IntInRange(
IntExpr::Int(1),
IntExpr::Int(2)
)))
);
}
fn e_var_par_identifier<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<Expr, E> {
let id = var_par_identifier(input)?;
Ok(Expr::VarParIdentifier(id))
}
fn e_bool_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<Expr, E> {
let b = bool_literal(input)?;
Ok(Expr::Bool(b))
}
fn e_int_expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let int = int_literal(input)?;
Ok(Expr::Int(int))
}
fn e_float_expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
let float = float_literal(input)?;
Ok(Expr::Float(float))
}
fn e_set_expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
let set = set_literal_expr(input)?;
Ok(Expr::Set(set))
}
fn e_array_of_bool_expr<'a, E: ParserError<&'a str>>(input: &mut &'a str) -> PResult<Expr, E> {
let v = array_of_bool_expr_literal(input)?;
Ok(Expr::ArrayOfBool(v))
}
fn e_array_of_int_expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let v = array_of_int_expr_literal(input)?;
Ok(Expr::ArrayOfInt(v))
}
fn e_array_of_float_expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
let v = array_of_float_expr_literal(input)?;
Ok(Expr::ArrayOfFloat(v))
}
fn e_array_of_set_expr<'a, E>(input: &mut &'a str) -> PResult<Expr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
let v = array_of_set_expr_literal(input)?;
Ok(Expr::ArrayOfSet(v))
}
#[derive(PartialEq, Clone, Debug)]
pub enum SetLiteralExpr {
IntInRange(IntExpr, IntExpr),
BoundedFloat(FloatExpr, FloatExpr),
SetFloats(Vec<FloatExpr>),
SetInts(Vec<IntExpr>),
}
fn set_literal_expr<'a, E>(input: &mut &'a str) -> PResult<SetLiteralExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
alt((
sle_int_in_range,
sle_bounded_float,
sle_set_of_ints,
sle_set_of_floats,
))
.parse_next(input)
}
fn sle_int_in_range<'a, E>(input: &mut &'a str) -> PResult<SetLiteralExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let lb = int_expr(input)?;
space_or_comment0(input)?;
"..".parse_next(input)?;
space_or_comment0(input)?;
let ub = int_expr(input)?;
Ok(SetLiteralExpr::IntInRange(lb, ub))
}
fn sle_bounded_float<'a, E>(input: &mut &'a str) -> PResult<SetLiteralExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
let lb = float_expr(input)?;
space_or_comment0(input)?;
"..".parse_next(input)?;
space_or_comment0(input)?;
let ub = float_expr(input)?;
Ok(SetLiteralExpr::BoundedFloat(lb, ub))
}
fn sle_set_of_ints<'a, E>(input: &mut &'a str) -> PResult<SetLiteralExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
'{'.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., int_expr, ',').parse_next(input)?;
space_or_comment0(input)?;
'}'.parse_next(input)?;
Ok(SetLiteralExpr::SetInts(v))
}
fn sle_set_of_floats<'a, E>(input: &mut &'a str) -> PResult<SetLiteralExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
'{'.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., float_expr, ',').parse_next(input)?;
space_or_comment0(input)?;
'}'.parse_next(input)?;
Ok(SetLiteralExpr::SetFloats(v))
}
#[derive(PartialEq, Clone, Debug)]
pub enum SetLiteral {
IntRange(i128, i128),
BoundedFloat(f64, f64),
SetFloats(Vec<f64>),
SetInts(Vec<i128>),
}
pub fn set_literal<'a, E>(input: &mut &'a str) -> PResult<SetLiteral, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
alt((
sl_int_range,
sl_bounded_float,
sl_set_of_ints,
sl_set_of_floats,
))
.parse_next(input)
}
fn sl_int_range<'a, E>(input: &mut &'a str) -> PResult<SetLiteral, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let lb = int_literal(input)?;
space_or_comment0(input)?;
"..".parse_next(input)?;
space_or_comment0(input)?;
let ub = int_literal(input)?;
Ok(SetLiteral::IntRange(lb, ub))
}
fn sl_bounded_float<'a, E>(input: &mut &'a str) -> PResult<SetLiteral, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
let lb = float_literal(input)?;
space_or_comment0(input)?;
"..".parse_next(input)?;
space_or_comment0(input)?;
let ub = float_literal(input)?;
Ok(SetLiteral::BoundedFloat(lb, ub))
}
fn sl_set_of_ints<'a, E>(input: &mut &'a str) -> PResult<SetLiteral, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
'{'.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., int_literal, ',').parse_next(input)?;
space_or_comment0(input)?;
'}'.parse_next(input)?;
Ok(SetLiteral::SetInts(v))
}
fn sl_set_of_floats<'a, E>(input: &mut &'a str) -> PResult<SetLiteral, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
'{'.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., float_literal, ',').parse_next(input)?;
space_or_comment0(input)?;
'}'.parse_next(input)?;
Ok(SetLiteral::SetFloats(v))
}
#[derive(PartialEq, Clone, Debug)]
pub enum ArrayOfBoolExpr {
Array(Vec<BoolExpr>),
VarParIdentifier(String),
}
pub fn array_of_bool_expr<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> PResult<ArrayOfBoolExpr, E> {
let id = opt(var_par_identifier).parse_next(input)?;
if let Some(id) = id {
Ok(ArrayOfBoolExpr::VarParIdentifier(id))
} else {
let v = array_of_bool_expr_literal(input)?;
Ok(ArrayOfBoolExpr::Array(v))
}
}
fn array_of_bool_expr_literal<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> PResult<Vec<BoolExpr>, E> {
'['.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., bool_expr, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(v)
}
pub fn array_of_bool_literal<'a, E: ParserError<&'a str>>(
input: &mut &'a str,
) -> PResult<Vec<bool>, E> {
'['.parse_next(input)?;
space_or_comment0(input)?;
let al = separated(0.., bool_literal, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(al)
}
impl TryFrom<Expr> for ArrayOfBoolExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::ArrayOfBool(value) => Ok(Self::Array(value)),
_ => Err(()),
}
}
}
impl From<ArrayOfBoolExpr> for Expr {
fn from(expr: ArrayOfBoolExpr) -> Self {
match expr {
ArrayOfBoolExpr::Array(value) => Self::ArrayOfBool(value),
ArrayOfBoolExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum ArrayOfIntExpr {
Array(Vec<IntExpr>),
VarParIdentifier(String),
}
pub fn array_of_int_expr<'a, E>(input: &mut &'a str) -> PResult<ArrayOfIntExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
let id = opt(var_par_identifier).parse_next(input)?;
if let Some(id) = id {
Ok(ArrayOfIntExpr::VarParIdentifier(id))
} else {
let v = array_of_int_expr_literal(input)?;
Ok(ArrayOfIntExpr::Array(v))
}
}
fn array_of_int_expr_literal<'a, E>(input: &mut &'a str) -> PResult<Vec<IntExpr>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., int_expr, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(v)
}
pub fn array_of_int_literal<'a, E>(input: &mut &'a str) -> PResult<Vec<i128>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseIntError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let al = separated(0.., int_literal, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(al)
}
impl TryFrom<Expr> for ArrayOfIntExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::ArrayOfInt(value) => Ok(Self::Array(value)),
_ => Err(()),
}
}
}
impl From<ArrayOfIntExpr> for Expr {
fn from(expr: ArrayOfIntExpr) -> Self {
match expr {
ArrayOfIntExpr::Array(value) => Self::ArrayOfInt(value),
ArrayOfIntExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum ArrayOfFloatExpr {
Array(Vec<FloatExpr>),
VarParIdentifier(String),
}
pub fn array_of_float_expr<'a, E>(input: &mut &'a str) -> PResult<ArrayOfFloatExpr, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
let id = opt(var_par_identifier).parse_next(input)?;
if let Some(id) = id {
Ok(ArrayOfFloatExpr::VarParIdentifier(id))
} else {
let v = array_of_float_expr_literal(input)?;
Ok(ArrayOfFloatExpr::Array(v))
}
}
fn array_of_float_expr_literal<'a, E>(input: &mut &'a str) -> PResult<Vec<FloatExpr>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., float_expr, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(v)
}
pub fn array_of_float_literal<'a, E>(input: &mut &'a str) -> PResult<Vec<f64>, E>
where
E: ParserError<&'a str> + FromExternalError<&'a str, std::num::ParseFloatError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let al = separated(0.., float_literal, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(al)
}
impl TryFrom<Expr> for ArrayOfFloatExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::ArrayOfFloat(value) => Ok(Self::Array(value)),
_ => Err(()),
}
}
}
impl From<ArrayOfFloatExpr> for Expr {
fn from(expr: ArrayOfFloatExpr) -> Self {
match expr {
ArrayOfFloatExpr::Array(value) => Self::ArrayOfFloat(value),
ArrayOfFloatExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}
#[derive(PartialEq, Clone, Debug)]
pub enum ArrayOfSetExpr {
Array(Vec<SetExpr>),
VarParIdentifier(String),
}
pub fn array_of_set_expr<'a, E>(input: &mut &'a str) -> PResult<ArrayOfSetExpr, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
let id = opt(var_par_identifier).parse_next(input)?;
if let Some(id) = id {
Ok(ArrayOfSetExpr::VarParIdentifier(id))
} else {
let v = array_of_set_expr_literal(input)?;
Ok(ArrayOfSetExpr::Array(v))
}
}
fn array_of_set_expr_literal<'a, E>(input: &mut &'a str) -> PResult<Vec<SetExpr>, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let v = separated(0.., set_expr, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(v)
}
pub fn array_of_set_literal<'a, E>(input: &mut &'a str) -> PResult<Vec<SetLiteral>, E>
where
E: ParserError<&'a str>
+ FromExternalError<&'a str, std::num::ParseIntError>
+ FromExternalError<&'a str, std::num::ParseFloatError>,
{
'['.parse_next(input)?;
space_or_comment0(input)?;
let al = separated(0.., set_literal, ',').parse_next(input)?;
space_or_comment0(input)?;
']'.parse_next(input)?;
Ok(al)
}
impl TryFrom<Expr> for ArrayOfSetExpr {
type Error = ();
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
match expr {
Expr::VarParIdentifier(id) => Ok(Self::VarParIdentifier(id)),
Expr::ArrayOfSet(value) => Ok(Self::Array(value)),
_ => Err(()),
}
}
}
impl From<ArrayOfSetExpr> for Expr {
fn from(expr: ArrayOfSetExpr) -> Self {
match expr {
ArrayOfSetExpr::Array(value) => Self::ArrayOfSet(value),
ArrayOfSetExpr::VarParIdentifier(id) => self::Expr::VarParIdentifier(id),
}
}
}