prql_ast/
expr.rs

1pub mod generic;
2mod ident;
3mod literal;
4mod ops;
5
6use std::collections::HashMap;
7
8pub use ident::Ident;
9pub use literal::{Literal, ValueAndUnit};
10pub use ops::{BinOp, UnOp};
11
12use enum_as_inner::EnumAsInner;
13use serde::{Deserialize, Serialize};
14
15use crate::Span;
16
17impl Expr {
18    pub fn new(kind: ExprKind) -> Self {
19        Expr {
20            kind,
21            span: None,
22            alias: None,
23        }
24    }
25}
26
27// The following code is tested by the tests_misc crate to match expr.rs in prql_compiler.
28
29/// Expr is anything that has a value and thus a type.
30/// If it cannot contain nested Exprs, is should be under [ExprKind::Literal].
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct Expr {
33    #[serde(flatten)]
34    pub kind: ExprKind,
35
36    #[serde(skip)]
37    pub span: Option<Span>,
38
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub alias: Option<String>,
41}
42
43#[derive(Debug, EnumAsInner, PartialEq, Clone, Serialize, Deserialize, strum::AsRefStr)]
44pub enum ExprKind {
45    Ident(Ident),
46    Literal(Literal),
47    Pipeline(Pipeline),
48
49    Tuple(Vec<Expr>),
50    Array(Vec<Expr>),
51    Range(Range),
52    Binary(BinaryExpr),
53    Unary(UnaryExpr),
54    FuncCall(FuncCall),
55    Func(Box<Func>),
56    SString(Vec<InterpolateItem>),
57    FString(Vec<InterpolateItem>),
58    Case(Vec<SwitchCase>),
59
60    /// placeholder for values provided after query is compiled
61    Param(String),
62
63    /// When used instead of function body, the function will be translated to a RQ operator.
64    /// Contains ident of the RQ operator.
65    Internal(String),
66}
67
68#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
69pub struct BinaryExpr {
70    pub left: Box<Expr>,
71    pub op: BinOp,
72    pub right: Box<Expr>,
73}
74
75#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
76pub struct UnaryExpr {
77    pub op: UnOp,
78    pub expr: Box<Expr>,
79}
80
81/// Function call.
82#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
83pub struct FuncCall {
84    pub name: Box<Expr>,
85    pub args: Vec<Expr>,
86    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
87    pub named_args: HashMap<String, Expr>,
88}
89
90/// Function called with possibly missing positional arguments.
91/// May also contain environment that is needed to evaluate the body.
92#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
93pub struct Func {
94    /// Type requirement for the function body expression.
95    pub return_ty: Option<Box<Expr>>,
96
97    /// Expression containing parameter (and environment) references.
98    pub body: Box<Expr>,
99
100    /// Positional function parameters.
101    pub params: Vec<FuncParam>,
102
103    /// Named function parameters.
104    pub named_params: Vec<FuncParam>,
105}
106
107#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
108pub struct FuncParam {
109    pub name: String,
110
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub ty: Option<Box<Expr>>,
113
114    pub default_value: Option<Box<Expr>>,
115}
116
117/// A value and a series of functions that are to be applied to that value one after another.
118#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
119pub struct Pipeline {
120    pub exprs: Vec<Expr>,
121}
122
123pub type Range = generic::Range<Box<Expr>>;
124pub type InterpolateItem = generic::InterpolateItem<Expr>;
125pub type SwitchCase = generic::SwitchCase<Box<Expr>>;
126
127impl From<Vec<Expr>> for Pipeline {
128    fn from(nodes: Vec<Expr>) -> Self {
129        Pipeline { exprs: nodes }
130    }
131}