1use std::collections::HashMap;
2
3use enum_as_inner::EnumAsInner;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6
7use crate::lexer::lr::Literal;
8use crate::parser::pr::ops::{BinOp, UnOp};
9use crate::parser::pr::Ty;
10use crate::span::Span;
11use crate::{generic, parser::SupportsDocComment};
12
13impl Expr {
14 pub fn new<K: Into<ExprKind>>(kind: K) -> Self {
15 Expr {
16 kind: kind.into(),
17 span: None,
18 alias: None,
19 doc_comment: None,
20 }
21 }
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
29pub struct Expr {
30 #[serde(flatten)]
31 pub kind: ExprKind,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub span: Option<Span>,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub alias: Option<String>,
38
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub doc_comment: Option<String>,
41}
42
43impl SupportsDocComment for Expr {
44 fn with_doc_comment(self, doc_comment: Option<String>) -> Self {
45 Self {
46 doc_comment,
47 ..self
48 }
49 }
50}
51
52#[derive(
53 Debug, EnumAsInner, PartialEq, Clone, Serialize, Deserialize, strum::AsRefStr, JsonSchema,
54)]
55pub enum ExprKind {
56 Ident(String),
57
58 Indirection {
61 base: Box<Expr>,
62 field: IndirectionKind,
63 },
64 #[cfg_attr(
65 feature = "serde_yaml",
66 serde(with = "serde_yaml::with::singleton_map"),
67 schemars(with = "Literal")
68 )]
69 Literal(Literal),
70 Pipeline(Pipeline),
71
72 Tuple(Vec<Expr>),
73 Array(Vec<Expr>),
74 Range(Range),
75 Binary(BinaryExpr),
76 Unary(UnaryExpr),
77 FuncCall(FuncCall),
78 Func(Box<Func>),
79 SString(Vec<InterpolateItem>),
80 FString(Vec<InterpolateItem>),
81 Case(Vec<SwitchCase>),
82
83 Param(String),
85
86 Internal(String),
89}
90
91impl ExprKind {
92 pub fn into_expr(self, span: Span) -> Expr {
93 Expr {
94 span: Some(span),
95 kind: self,
96 alias: None,
97 doc_comment: None,
98 }
99 }
100}
101
102#[derive(Debug, EnumAsInner, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
103pub enum IndirectionKind {
104 Name(String),
105 Position(i64),
106 Star,
107}
108
109#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
111pub struct BinaryExpr {
112 pub left: Box<Expr>,
113 pub op: BinOp,
114 pub right: Box<Expr>,
115}
116
117#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
119pub struct UnaryExpr {
120 pub op: UnOp,
121 pub expr: Box<Expr>,
122}
123
124#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
126pub struct FuncCall {
127 pub name: Box<Expr>,
128 pub args: Vec<Expr>,
129 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
130 pub named_args: HashMap<String, Expr>,
131}
132
133#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
136pub struct Func {
137 pub return_ty: Option<Ty>,
139
140 pub body: Box<Expr>,
142
143 pub params: Vec<FuncParam>,
145
146 pub named_params: Vec<FuncParam>,
148
149 pub generic_type_params: Vec<GenericTypeParam>,
151}
152
153#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
154pub struct FuncParam {
155 pub name: String,
156
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub ty: Option<Ty>,
159
160 pub default_value: Option<Box<Expr>>,
161}
162
163#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
164pub struct GenericTypeParam {
165 pub name: String,
167
168 pub domain: Vec<Ty>,
169}
170
171#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, JsonSchema)]
173pub struct Pipeline {
174 pub exprs: Vec<Expr>,
175}
176
177pub type Range = generic::Range<Box<Expr>>;
178pub type InterpolateItem = generic::InterpolateItem<Expr>;
179pub type SwitchCase = generic::SwitchCase<Box<Expr>>;
180
181impl From<Literal> for ExprKind {
182 fn from(value: Literal) -> Self {
183 ExprKind::Literal(value)
184 }
185}
186
187impl From<Func> for ExprKind {
188 fn from(value: Func) -> Self {
189 ExprKind::Func(Box::new(value))
190 }
191}