use serde::{Deserialize, Serialize};
use crate::span::Spanned;
use crate::types::Type;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Program {
pub statements: Vec<Spanned<Stmt>>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Stmt {
ConnectorDecl {
name: String,
connector_type: String,
params: Vec<ConnectorParam>,
},
StreamDecl {
name: String,
type_annotation: Option<Type>,
source: StreamSource,
ops: Vec<StreamOp>,
#[serde(default)]
op_spans: Vec<crate::span::Span>,
},
EventDecl {
name: String,
extends: Option<String>,
fields: Vec<Field>,
},
TypeDecl {
name: String,
ty: Option<Type>,
fields: Vec<Field>,
},
VarDecl {
mutable: bool,
name: String,
ty: Option<Type>,
value: Expr,
},
ConstDecl {
name: String,
ty: Option<Type>,
value: Expr,
},
FnDecl {
name: String,
params: Vec<Param>,
ret: Option<Type>,
body: Vec<Spanned<Self>>,
},
Config {
name: String,
items: Vec<ConfigItem>,
},
Import {
path: String,
alias: Option<String>,
},
ImportWasmFn {
name: String,
params: Vec<Param>,
ret: Option<Type>,
wasm_path: String,
},
Expr(Expr),
If {
cond: Expr,
then_branch: Vec<Spanned<Self>>,
elif_branches: Vec<(Expr, Vec<Spanned<Self>>)>,
else_branch: Option<Vec<Spanned<Self>>>,
},
For {
var: String,
iter: Expr,
body: Vec<Spanned<Self>>,
},
While {
cond: Expr,
body: Vec<Spanned<Self>>,
},
Return(Option<Expr>),
Break,
Continue,
Emit {
event_type: String,
fields: Vec<NamedArg>,
},
Assignment {
name: String,
value: Expr,
},
PatternDecl {
name: String,
expr: SasePatternExpr,
within: Option<Expr>,
partition_by: Option<Expr>,
},
ContextDecl {
name: String,
cores: Option<Vec<usize>>,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ConnectorParam {
pub name: String,
pub value: ConfigValue,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum SasePatternExpr {
Seq(Vec<SasePatternItem>),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SasePatternItem {
pub event_type: String,
pub alias: Option<String>,
pub kleene: Option<KleeneOp>,
pub filter: Option<Expr>,
pub monotonic: Option<MonotonicOp>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum KleeneOp {
Plus,
Star,
Optional,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum MonotonicOp {
Increasing(String),
Decreasing(String),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum StreamSource {
Ident(String),
IdentWithAlias {
name: String,
alias: String,
},
IdentWithFilterAndAlias {
name: String,
filter: Expr,
alias: Option<String>,
},
AllWithAlias {
name: String,
alias: Option<String>,
},
FromConnector {
event_type: String,
connector_name: String,
params: Vec<ConnectorParam>,
},
Merge(Vec<InlineStreamDecl>),
Join(Vec<JoinClause>),
Sequence(SequenceDecl),
Timer(TimerDecl),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TimerDecl {
pub interval: Expr,
pub initial_delay: Option<Box<Expr>>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SequenceDecl {
pub match_all: bool,
pub timeout: Option<Box<Expr>>,
pub steps: Vec<SequenceStepDecl>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SequenceStepDecl {
pub alias: String,
pub event_type: String,
pub filter: Option<Expr>,
pub timeout: Option<Box<Expr>>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct InlineStreamDecl {
pub name: String,
pub source: String,
pub filter: Option<Expr>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum JoinType {
#[default]
Inner,
Left,
Right,
Full,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct JoinClause {
pub name: String,
pub source: String,
pub on: Option<Expr>,
#[serde(default)]
pub join_type: JoinType,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum StreamOp {
Where(Expr),
Select(Vec<SelectItem>),
Window(WindowArgs),
Aggregate(Vec<AggItem>),
Having(Expr),
PartitionBy(Expr),
OrderBy(Vec<OrderItem>),
Limit(Expr),
Distinct(Option<Expr>),
Map(Expr),
Filter(Expr),
Tap(Vec<NamedArg>),
Print(Vec<Expr>),
Log(Vec<NamedArg>),
Emit {
output_type: Option<String>,
fields: Vec<NamedArg>,
target_context: Option<String>,
},
To {
connector_name: String,
params: Vec<ConnectorParam>,
},
ToExpr(Expr),
Pattern(PatternDef),
Concurrent(Vec<NamedArg>),
Process(Expr),
OnError(Expr),
Collect,
On(Expr),
FollowedBy(FollowedByClause),
Within(Expr),
Not(FollowedByClause),
Fork(Vec<ForkPath>),
Any(Option<usize>),
All,
First,
Context(String),
Watermark(Vec<NamedArg>),
AllowedLateness(Expr),
TrendAggregate(Vec<TrendAggItem>),
Score(ScoreSpec),
Forecast(ForecastSpec),
Enrich(EnrichSpec),
Alert(Vec<NamedArg>),
SelectionMode(SelectionMode),
EmissionMode(EmissionMode),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SelectionMode {
Strict,
Stnm,
Stam,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EmissionMode {
Each,
Longest,
Subsets,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ForkPath {
pub name: String,
pub ops: Vec<StreamOp>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TrendAggItem {
pub alias: String,
pub func: String,
pub arg: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ScoreSpec {
pub model_path: String,
pub inputs: Vec<String>,
pub outputs: Vec<String>,
#[serde(default)]
pub gpu: bool,
#[serde(default = "default_batch_size")]
pub batch_size: usize,
#[serde(default)]
pub device_id: i32,
}
const fn default_batch_size() -> usize {
1
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ForecastSpec {
pub confidence: Option<Expr>,
pub horizon: Option<Expr>,
pub warmup: Option<Expr>,
pub max_depth: Option<Expr>,
pub hawkes: Option<Expr>,
pub conformal: Option<Expr>,
pub mode: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EnrichSpec {
pub connector_name: String,
pub key_expr: Box<Expr>,
pub fields: Vec<String>,
pub cache_ttl: Option<Expr>,
pub timeout: Option<Expr>,
pub fallback: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FollowedByClause {
pub event_type: String,
pub filter: Option<Expr>,
pub alias: Option<String>,
pub match_all: bool,
pub monotonic: Option<MonotonicOp>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum SelectItem {
Field(String),
Alias(String, Expr),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AggItem {
pub alias: String,
pub expr: Expr,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OrderItem {
pub expr: Expr,
pub descending: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct WindowArgs {
pub duration: Expr,
pub sliding: Option<Expr>,
pub policy: Option<Expr>,
pub session_gap: Option<Expr>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PatternDef {
pub name: String,
pub matcher: Expr,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NamedArg {
pub name: String,
pub value: Expr,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Field {
pub name: String,
pub ty: Type,
pub optional: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Param {
pub name: String,
pub ty: Type,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Expr {
Null,
Bool(bool),
Int(i64),
Float(f64),
Str(String),
Duration(u64),
Timestamp(i64),
Array(Vec<Self>),
Map(Vec<(String, Self)>),
Ident(String),
Binary {
op: BinOp,
left: Box<Self>,
right: Box<Self>,
},
Unary {
op: UnaryOp,
expr: Box<Self>,
},
Member {
expr: Box<Self>,
member: String,
},
OptionalMember {
expr: Box<Self>,
member: String,
},
Index {
expr: Box<Self>,
index: Box<Self>,
},
Slice {
expr: Box<Self>,
start: Option<Box<Self>>,
end: Option<Box<Self>>,
},
Call {
func: Box<Self>,
args: Vec<Arg>,
},
Lambda {
params: Vec<String>,
body: Box<Self>,
},
If {
cond: Box<Self>,
then_branch: Box<Self>,
else_branch: Box<Self>,
},
Coalesce {
expr: Box<Self>,
default: Box<Self>,
},
Range {
start: Box<Self>,
end: Box<Self>,
inclusive: bool,
},
Block {
stmts: Vec<(String, Option<Type>, Self, bool)>,
result: Box<Self>,
},
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Arg {
Positional(Expr),
Named(String, Expr),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Mod,
Pow,
Eq,
NotEq,
Lt,
Le,
Gt,
Ge,
In,
NotIn,
Is,
And,
Or,
Xor,
FollowedBy,
BitAnd,
BitOr,
BitXor,
Shl,
Shr,
}
impl BinOp {
pub const fn as_str(&self) -> &'static str {
match self {
Self::Add => "+",
Self::Sub => "-",
Self::Mul => "*",
Self::Div => "/",
Self::Mod => "%",
Self::Pow => "**",
Self::Eq => "==",
Self::NotEq => "!=",
Self::Lt => "<",
Self::Le => "<=",
Self::Gt => ">",
Self::Ge => ">=",
Self::In => "in",
Self::NotIn => "not in",
Self::Is => "is",
Self::And => "and",
Self::Or => "or",
Self::Xor => "xor",
Self::FollowedBy => "->",
Self::BitAnd => "&",
Self::BitOr => "|",
Self::BitXor => "^",
Self::Shl => "<<",
Self::Shr => ">>",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum UnaryOp {
Neg,
Not,
BitNot,
}
impl UnaryOp {
pub const fn as_str(&self) -> &'static str {
match self {
Self::Neg => "-",
Self::Not => "not",
Self::BitNot => "~",
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ConfigItem {
Value(String, ConfigValue),
Nested(String, Vec<Self>),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ConfigValue {
Bool(bool),
Int(i64),
Float(f64),
Str(String),
Duration(u64),
Ident(String),
Array(Vec<Self>),
Map(Vec<(String, Self)>),
Concat(Vec<Self>),
}
impl ConfigValue {
pub fn as_string(&self) -> Option<&str> {
match self {
Self::Str(s) => Some(s),
Self::Ident(s) => Some(s),
_ => None,
}
}
pub const fn as_int(&self) -> Option<i64> {
match self {
Self::Int(i) => Some(*i),
Self::Float(f) => Some(*f as i64),
_ => None,
}
}
pub const fn as_float(&self) -> Option<f64> {
match self {
Self::Float(f) => Some(*f),
Self::Int(i) => Some(*i as f64),
_ => None,
}
}
pub const fn as_bool(&self) -> Option<bool> {
match self {
Self::Bool(b) => Some(*b),
_ => None,
}
}
}