use selene_core::DbString;
use crate::ast::{
expr::ValueExpr,
pattern::{GraphPattern, MatchClause},
span::SourceSpan,
statement::ReturnClause,
util::NonEmpty,
};
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct MutationPipeline {
pub statements: NonEmpty<MutationStatement>,
pub terminator: Option<MutationTerminator>,
pub span: SourceSpan,
}
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub enum MutationStatement {
Match(MatchClause),
Filter(ValueExpr),
Insert(InsertStatement),
Set(Vec<SetItem>),
Remove(Vec<RemoveItem>),
Delete(DeleteStatement),
}
impl MutationStatement {
#[must_use]
pub fn span(&self) -> SourceSpan {
match self {
Self::Match(value) => value.span,
Self::Filter(value) => value.span(),
Self::Insert(value) => value.span,
Self::Set(values) => span_from_iter(values.iter().map(SetItem::span)),
Self::Remove(values) => span_from_iter(values.iter().map(RemoveItem::span)),
Self::Delete(value) => value.span,
}
}
}
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub enum MutationTerminator {
Return(ReturnClause),
Finish(SourceSpan),
}
impl MutationTerminator {
#[must_use]
pub const fn span(&self) -> SourceSpan {
match self {
Self::Return(value) => value.span,
Self::Finish(span) => *span,
}
}
}
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct InsertStatement {
pub patterns: Vec<GraphPattern>,
pub span: SourceSpan,
}
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub enum SetItem {
Property {
target: DbString,
key: DbString,
value: ValueExpr,
span: SourceSpan,
},
PropertyMerge {
target: DbString,
properties: Vec<(DbString, ValueExpr)>,
span: SourceSpan,
},
Label {
target: DbString,
label: DbString,
span: SourceSpan,
},
}
impl SetItem {
#[must_use]
pub const fn span(&self) -> SourceSpan {
match self {
Self::Property { span, .. }
| Self::PropertyMerge { span, .. }
| Self::Label { span, .. } => *span,
}
}
}
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub enum RemoveItem {
Property {
target: DbString,
key: DbString,
span: SourceSpan,
},
Label {
target: DbString,
label: DbString,
span: SourceSpan,
},
}
impl RemoveItem {
#[must_use]
pub const fn span(&self) -> SourceSpan {
match self {
Self::Property { span, .. } | Self::Label { span, .. } => *span,
}
}
}
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct DeleteStatement {
pub mode: DeleteMode,
pub items: Vec<DbString>,
pub span: SourceSpan,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum DeleteMode {
Bare,
Detach,
NoDetach,
}
fn span_from_iter(mut spans: impl Iterator<Item = SourceSpan>) -> SourceSpan {
let Some(first) = spans.next() else {
return SourceSpan::default();
};
spans.fold(first, SourceSpan::merge)
}