prqlc_ast/
types.rs

1use enum_as_inner::EnumAsInner;
2use serde::{Deserialize, Serialize};
3use strum::AsRefStr;
4
5use super::{Ident, Literal};
6use crate::Span;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct Ty {
10    pub kind: TyKind,
11
12    pub span: Option<Span>,
13
14    /// Name inferred from the type declaration.
15    pub name: Option<String>,
16}
17
18#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, EnumAsInner, AsRefStr)]
19pub enum TyKind {
20    /// Identifier that still needs to be resolved.
21    Ident(Ident),
22
23    /// Type of a built-in primitive type
24    Primitive(PrimitiveSet),
25
26    /// Type that contains only a one value
27    Singleton(Literal),
28
29    /// Union of sets (sum)
30    Union(Vec<(Option<String>, Ty)>),
31
32    /// Type of tuples (product)
33    Tuple(Vec<TyTupleField>),
34
35    /// Type of arrays
36    Array(Box<Ty>),
37
38    /// Type of functions with defined params and return types.
39    Function(Option<TyFunc>),
40
41    /// Type of every possible value. Super type of all other types.
42    /// The breaker of chains. Mother of types.
43    Any,
44
45    /// Type that is the largest subtype of `base` while not a subtype of `exclude`.
46    Difference { base: Box<Ty>, exclude: Box<Ty> },
47
48    /// A generic argument. Contains id of the function call node and generic type param name.
49    GenericArg((usize, String)),
50}
51
52#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, EnumAsInner)]
53pub enum TyTupleField {
54    /// Named tuple element.
55    Single(Option<String>, Option<Ty>),
56
57    /// Placeholder for possibly many elements.
58    /// Means "and other unmentioned columns". Does not mean "all columns".
59    Wildcard(Option<Ty>),
60}
61
62/// Built-in sets.
63#[derive(
64    Debug, Clone, Serialize, Deserialize, PartialEq, Eq, strum::EnumString, strum::Display,
65)]
66pub enum PrimitiveSet {
67    #[strum(to_string = "int")]
68    Int,
69    #[strum(to_string = "float")]
70    Float,
71    #[strum(to_string = "bool")]
72    Bool,
73    #[strum(to_string = "text")]
74    Text,
75    #[strum(to_string = "date")]
76    Date,
77    #[strum(to_string = "time")]
78    Time,
79    #[strum(to_string = "timestamp")]
80    Timestamp,
81}
82
83// Type of a function
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub struct TyFunc {
86    pub name_hint: Option<Ident>,
87    pub args: Vec<Option<Ty>>,
88    pub return_ty: Box<Option<Ty>>,
89}
90
91impl Ty {
92    pub fn new<K: Into<TyKind>>(kind: K) -> Ty {
93        Ty {
94            kind: kind.into(),
95            span: None,
96            name: None,
97        }
98    }
99
100    pub fn relation(tuple_fields: Vec<TyTupleField>) -> Self {
101        let tuple = Ty::new(TyKind::Tuple(tuple_fields));
102        Ty::new(TyKind::Array(Box::new(tuple)))
103    }
104
105    pub fn never() -> Self {
106        Ty::new(TyKind::Union(Vec::new()))
107    }
108
109    pub fn is_never(&self) -> bool {
110        self.kind.as_union().map_or(false, |x| x.is_empty())
111    }
112
113    pub fn as_relation(&self) -> Option<&Vec<TyTupleField>> {
114        self.kind.as_array()?.kind.as_tuple()
115    }
116
117    pub fn as_relation_mut(&mut self) -> Option<&mut Vec<TyTupleField>> {
118        self.kind.as_array_mut()?.kind.as_tuple_mut()
119    }
120
121    pub fn into_relation(self) -> Option<Vec<TyTupleField>> {
122        self.kind.into_array().ok()?.kind.into_tuple().ok()
123    }
124
125    pub fn is_relation(&self) -> bool {
126        match &self.kind {
127            TyKind::Array(elem) => {
128                matches!(elem.kind, TyKind::Tuple(_))
129            }
130            _ => false,
131        }
132    }
133}
134
135impl TyTupleField {
136    pub fn ty(&self) -> Option<&Ty> {
137        match self {
138            TyTupleField::Single(_, ty) => ty.as_ref(),
139            TyTupleField::Wildcard(ty) => ty.as_ref(),
140        }
141    }
142}
143
144impl From<PrimitiveSet> for TyKind {
145    fn from(value: PrimitiveSet) -> Self {
146        TyKind::Primitive(value)
147    }
148}
149
150impl From<TyFunc> for TyKind {
151    fn from(value: TyFunc) -> Self {
152        TyKind::Function(Some(value))
153    }
154}
155
156impl From<Literal> for TyKind {
157    fn from(value: Literal) -> Self {
158        TyKind::Singleton(value)
159    }
160}