use nom::Parser;
use nom::bytes::complete::tag_no_case;
use nom::{
IResult,
branch::alt,
combinator::{map, opt},
sequence::{pair, preceded},
};
use crate::search::number::parse_number;
use super::expression::{Expression, parse_or_expression};
use super::offset::{FromOffset, parse_from_offset};
use super::order::{Order, OrderKeyword, parse_order, parse_order_keyword};
use super::wsi::wsi;
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum SearchClause {
Limit(usize),
Expression(Expression),
From(FromOffset),
OrderBy(Order, Option<OrderKeyword>),
}
pub(crate) fn parse_expression(input: &str) -> IResult<&str, SearchClause> {
map(
(opt(wsi(tag_no_case("where"))), wsi(parse_or_expression)),
|(_, e)| SearchClause::Expression(e),
)
.parse(input)
}
pub(crate) fn parse_from_offset_clause(input: &str) -> IResult<&str, SearchClause> {
map(parse_from_offset, SearchClause::From).parse(input)
}
pub(crate) fn parse_limit(input: &str) -> IResult<&str, SearchClause> {
map(
preceded(wsi(tag_no_case("limit")), wsi(parse_number)),
SearchClause::Limit,
)
.parse(input)
}
pub(crate) fn parse_order_by(input: &str) -> IResult<&str, SearchClause> {
map(
preceded(
pair(
wsi(alt((tag_no_case("order"), tag_no_case("sort")))),
wsi(tag_no_case("by")),
),
pair(parse_order, opt(parse_order_keyword)),
),
|(o, oo)| SearchClause::OrderBy(o, oo),
)
.parse(input)
}
#[test]
fn test_parse_offset_clause() {
assert_eq!(
parse_from_offset_clause(r#"from end - 10"#),
Ok(("", SearchClause::From(FromOffset::OffsetTail(10))))
);
}