use super::base::{parse_operator, parse_value};
use super::expressions::{parse_expression, parse_multiplicative_expr};
use crate::ast::*;
use nom::{
IResult, Parser,
bytes::complete::tag_no_case,
character::complete::{multispace0, multispace1},
combinator::opt,
multi::separated_list0,
sequence::preceded,
};
pub fn parse_case(input: &str) -> IResult<&str, Expr> {
let (input, _) = tag_no_case("case").parse(input)?;
let (input, _) = multispace1(input)?;
let (input, when_clauses) = separated_list0(multispace1, parse_when).parse(input)?;
let (input, _) = multispace0(input)?;
let (input, else_value) = opt(preceded(
(tag_no_case("else"), multispace1),
parse_expression,
))
.parse(input)?;
let (input, _) = multispace0(input)?;
let (input, _) = tag_no_case("end").parse(input)?;
Ok((
input,
Expr::Case {
when_clauses,
else_value: else_value.map(Box::new),
alias: None,
},
))
}
pub fn parse_when(input: &str) -> IResult<&str, (Condition, Box<Expr>)> {
let (input, _) = tag_no_case("when").parse(input)?;
let (input, _) = multispace1(input)?;
let (input, left_expr) = parse_multiplicative_expr(input)?; let (input, _) = multispace0(input)?;
let (input, op) = parse_operator(input)?;
let (input, _) = multispace0(input)?;
let (input, val) = if matches!(op, Operator::IsNull | Operator::IsNotNull) {
(input, Value::Null)
} else {
parse_value(input)?
};
let (input, _) = multispace0(input)?;
let (input, _) = tag_no_case("then").parse(input)?;
let (input, _) = multispace1(input)?;
let (input, then_expr) = parse_expression(input)?;
Ok((
input,
(
Condition {
left: left_expr,
op,
value: val,
is_array_unnest: false,
},
Box::new(then_expr),
),
))
}