muninn_query 0.5.0

Query langugage for muninn logging stack
Documentation
use crate::{
  ast::{Duration, RelativeTime, TimeAnchor, Value},
  parser::{
    keyword,
    utils::{int16, IResult, LocatedSpan},
  },
};
use nom::{
  branch::alt,
  bytes::complete::tag,
  character::complete::{multispace0, multispace1},
  combinator::map,
  sequence::tuple,
};

pub(crate) fn relative_time_value(i: LocatedSpan) -> IResult<Value> {
  map(relative_time, Value::RelativeTime)(i)
}

fn relative_time(i: LocatedSpan) -> IResult<RelativeTime> {
  alt((now, relative_time_duration))(i)
}

fn now(i: LocatedSpan) -> IResult<RelativeTime> {
  map(keyword("now"), |_| RelativeTime::Now)(i)
}

fn relative_time_duration(i: LocatedSpan) -> IResult<RelativeTime> {
  map(
    tuple((duration, multispace1, time_anchor)),
    |(duration, _, time_anchor)| RelativeTime::Duration(duration, time_anchor),
  )(i)
}

fn duration(i: LocatedSpan) -> IResult<Duration> {
  alt((
    duration_seconds,
    duration_minutes,
    duration_hours,
    duration_days,
    duration_weeks,
    duration_months,
    duration_years,
  ))(i)
}

fn duration_seconds(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("seconds"), tag("second"))))),
    |(amount, _, _)| Duration::Seconds(amount),
  )(i)
}
fn duration_minutes(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("minutes"), tag("minute"))))),
    |(amount, _, _)| Duration::Minutes(amount),
  )(i)
}
fn duration_hours(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("hours"), tag("hour"))))),
    |(amount, _, _)| Duration::Hours(amount),
  )(i)
}
fn duration_days(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("days"), tag("day"))))),
    |(amount, _, _)| Duration::Days(amount),
  )(i)
}
fn duration_weeks(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("weeks"), tag("week"))))),
    |(amount, _, _)| Duration::Weeks(amount),
  )(i)
}
fn duration_months(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("months"), tag("month"))))),
    |(amount, _, _)| Duration::Months(amount),
  )(i)
}
fn duration_years(i: LocatedSpan) -> IResult<Duration> {
  map(
    tuple((int16, multispace0, alt((tag("years"), tag("year"))))),
    |(amount, _, _)| Duration::Years(amount),
  )(i)
}

fn time_anchor(i: LocatedSpan) -> IResult<TimeAnchor> {
  map(tag("ago"), |_| TimeAnchor::Ago)(i)
}

#[cfg(test)]
mod tests {

  use super::relative_time;
  use crate::{
    ast::{Duration, RelativeTime, TimeAnchor},
    parser::utils::{span, unwrap_span},
  };

  #[test]
  fn test_relative_time() {
    assert_eq!(
      relative_time(span("now")).map(unwrap_span),
      Ok(("", RelativeTime::Now))
    );

    assert_eq!(
      relative_time(span("1second ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Seconds(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 seconds ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Seconds(2), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("1 minute ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Minutes(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 minutes ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Minutes(2), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("1 hour ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Hours(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 hours ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Hours(2), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("1 day ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Days(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 days ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Days(2), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("1 week ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Weeks(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 weeks ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Weeks(2), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("1 month ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Months(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 months ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Months(2), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("1 year ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Years(1), TimeAnchor::Ago)
      ))
    );

    assert_eq!(
      relative_time(span("2 years ago")).map(unwrap_span),
      Ok((
        "",
        RelativeTime::Duration(Duration::Years(2), TimeAnchor::Ago)
      ))
    );
  }
}