use crate::sql::expression::{expression, Expression}; use crate::sql::statements::create::{create, CreateStatement}; use crate::sql::statements::delete::{delete, DeleteStatement}; use crate::sql::statements::ifelse::{ifelse, IfelseStatement}; use crate::sql::statements::insert::{insert, InsertStatement}; use crate::sql::statements::relate::{relate, RelateStatement}; use crate::sql::statements::select::{select, SelectStatement}; use crate::sql::statements::update::{update, UpdateStatement}; use crate::sql::statements::upsert::{upsert, UpsertStatement}; use nom::branch::alt; use nom::bytes::complete::tag; use nom::combinator::map; use nom::IResult; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] pub enum Subquery { Expression(Expression), Select(SelectStatement), Create(CreateStatement), Update(UpdateStatement), Delete(DeleteStatement), Relate(RelateStatement), Insert(InsertStatement), Upsert(UpsertStatement), Ifelse(IfelseStatement), } impl fmt::Display for Subquery { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Subquery::Expression(v) => write!(f, "({})", v), Subquery::Select(v) => write!(f, "({})", v), Subquery::Create(v) => write!(f, "({})", v), Subquery::Update(v) => write!(f, "({})", v), Subquery::Delete(v) => write!(f, "({})", v), Subquery::Relate(v) => write!(f, "({})", v), Subquery::Insert(v) => write!(f, "({})", v), Subquery::Upsert(v) => write!(f, "({})", v), Subquery::Ifelse(v) => write!(f, "{}", v), } } } pub fn subquery(i: &str) -> IResult<&str, Subquery> { alt((subquery_ifelse, subquery_others))(i) } fn subquery_ifelse(i: &str) -> IResult<&str, Subquery> { let (i, v) = map(ifelse, |v| Subquery::Ifelse(v))(i)?; Ok((i, v)) } fn subquery_others(i: &str) -> IResult<&str, Subquery> { let (i, _) = tag("(")(i)?; let (i, v) = alt(( map(expression, |v| Subquery::Expression(v)), map(select, |v| Subquery::Select(v)), map(create, |v| Subquery::Create(v)), map(update, |v| Subquery::Update(v)), map(delete, |v| Subquery::Delete(v)), map(relate, |v| Subquery::Relate(v)), map(insert, |v| Subquery::Insert(v)), map(upsert, |v| Subquery::Upsert(v)), ))(i)?; let (i, _) = tag(")")(i)?; Ok((i, v)) }