nom_sql/
case.rs

1use std::fmt;
2
3use column::Column;
4use common::{column_identifier_no_alias, literal, Literal};
5use condition::{condition_expr, ConditionExpression};
6
7use nom::bytes::complete::tag_no_case;
8use nom::character::complete::multispace0;
9use nom::combinator::opt;
10use nom::sequence::{delimited, terminated, tuple};
11use nom::IResult;
12
13#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
14pub enum ColumnOrLiteral {
15    Column(Column),
16    Literal(Literal),
17}
18
19impl fmt::Display for ColumnOrLiteral {
20    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21        match *self {
22            ColumnOrLiteral::Column(ref c) => write!(f, "{}", c)?,
23            ColumnOrLiteral::Literal(ref l) => write!(f, "{}", l.to_string())?,
24        }
25        Ok(())
26    }
27}
28
29#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
30pub struct CaseWhenExpression {
31    pub condition: ConditionExpression,
32    pub then_expr: ColumnOrLiteral,
33    pub else_expr: Option<ColumnOrLiteral>,
34}
35
36impl fmt::Display for CaseWhenExpression {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        write!(f, "CASE WHEN {} THEN {}", self.condition, self.then_expr)?;
39        if let Some(ref expr) = self.else_expr {
40            write!(f, " ELSE {}", expr)?;
41        }
42        Ok(())
43    }
44}
45
46pub fn case_when_column(i: &[u8]) -> IResult<&[u8], CaseWhenExpression> {
47    let (remaining_input, (_, _, condition, _, _, _, column, _, else_val, _)) = tuple((
48        tag_no_case("case when"),
49        multispace0,
50        condition_expr,
51        multispace0,
52        tag_no_case("then"),
53        multispace0,
54        column_identifier_no_alias,
55        multispace0,
56        opt(delimited(
57            terminated(tag_no_case("else"), multispace0),
58            literal,
59            multispace0,
60        )),
61        tag_no_case("end"),
62    ))(i)?;
63
64    let then_expr = ColumnOrLiteral::Column(column);
65    let else_expr = else_val.map(|v| ColumnOrLiteral::Literal(v));
66
67    Ok((
68        remaining_input,
69        CaseWhenExpression {
70            condition,
71            then_expr,
72            else_expr,
73        },
74    ))
75}