pddl 0.2.0

A PDDL 3.1 parser, strongly typed
Documentation
//! Provides parsers for simple duration constraints.

use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::character::complete::multispace1;
use nom::combinator::map;
use nom::sequence::preceded;
use nom::Parser;

use crate::parsers::{parens, prefix_expr, ParseResult, Span};
use crate::parsers::{parse_d_op, parse_d_value, parse_time_specifier};
use crate::types::SimpleDurationConstraint;

/// Parses a simple duration constraint.
///
/// ## Example
/// ```
/// # use pddl::parsers::{parse_simple_duration_constraint, preamble::*};
/// # use pddl::{DOp, DurationValue, FunctionType, SimpleDurationConstraint, TimeSpecifier};
/// let input = "(>= ?duration 1.23)";
/// assert!(parse_simple_duration_constraint(input).is_value(
///     SimpleDurationConstraint::op(
///         DOp::GreaterOrEqual,
///         DurationValue::number(1.23)
///     )
/// ));
///
/// let input = "(at end (<= ?duration 1.23))";
/// assert!(parse_simple_duration_constraint(input).is_value(
///     SimpleDurationConstraint::at(
///         TimeSpecifier::End,
///         SimpleDurationConstraint::Op(
///             DOp::LessThanOrEqual,
///             DurationValue::number(1.23)
///         )
///     )
/// ));
///```
pub fn parse_simple_duration_constraint<'a, T: Into<Span<'a>>>(
    input: T,
) -> ParseResult<'a, SimpleDurationConstraint> {
    let op = map(
        parens((
            parse_d_op,
            preceded((multispace1, tag("?duration"), multispace1), parse_d_value),
        )),
        SimpleDurationConstraint::from,
    );

    let at = map(
        prefix_expr(
            "at",
            (
                parse_time_specifier,
                preceded(multispace1, parse_simple_duration_constraint),
            ),
        ),
        SimpleDurationConstraint::from,
    );

    alt((op, at)).parse(input.into())
}

impl crate::parsers::Parser for SimpleDurationConstraint {
    type Item = SimpleDurationConstraint;

    /// See [`parse_simple_duration_constraint`].
    fn parse<'a, S: Into<Span<'a>>>(input: S) -> ParseResult<'a, Self::Item> {
        parse_simple_duration_constraint(input)
    }
}

#[cfg(test)]
mod tests {
    use crate::parsers::preamble::*;
    use crate::{DurationOperator, DurationValue, SimpleDurationConstraint, TimeSpecifier};

    #[test]
    fn test_parse() {
        let input = "(>= ?duration 1.23)";
        assert!(
            SimpleDurationConstraint::parse(input).is_value(SimpleDurationConstraint::op(
                DurationOperator::GreaterOrEqual,
                DurationValue::number(1.23)
            ))
        );

        let input = "(at end (<= ?duration 1.23))";
        assert!(
            SimpleDurationConstraint::parse(input).is_value(SimpleDurationConstraint::at(
                TimeSpecifier::End,
                SimpleDurationConstraint::Op(
                    DurationOperator::LessThanOrEqual,
                    DurationValue::number(1.23)
                )
            ))
        );
    }
}