use std::fmt::Display;
use nom::{
IResult, Parser,
branch::alt,
bytes::{complete::tag, tag_no_case},
combinator::{map, value},
sequence::preceded,
};
use super::{
compare::parse_equal,
number::parse_number,
symbol::{parse_end_keyword, parse_offset},
timestamp::parse_timestamp,
wsi::wsi,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FromOffset {
Beginning,
End,
Offset(i64),
OffsetTail(i64),
Timestamp(i64),
}
impl Display for FromOffset {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FromOffset::Beginning => write!(f, "beginning"),
FromOffset::End => write!(f, "end"),
FromOffset::Offset(o) => write!(f, "{o}"),
FromOffset::OffsetTail(o) => write!(f, "end - {o}"),
FromOffset::Timestamp(_) => write!(f, ""),
}
}
}
pub(crate) fn parse_from_offset(input: &str) -> IResult<&str, FromOffset> {
preceded(
wsi(tag_no_case("from")),
alt((
map(wsi(parse_timestamp), |t| {
FromOffset::Timestamp(t.to_utc().timestamp_millis())
}),
value(
FromOffset::Beginning,
wsi(alt((tag("beginning"), tag_no_case("begin")))),
),
map(
(parse_offset, parse_equal, wsi(parse_number)),
|(_, _, d)| FromOffset::Offset(d),
),
map(wsi(parse_number), FromOffset::Offset),
map(
(parse_end_keyword, wsi(tag("-")), wsi(parse_number)),
|(_, _, r)| FromOffset::OffsetTail(r),
),
value(FromOffset::End, parse_end_keyword),
)),
)
.parse(input)
}