prqlc_parser/parser/pr/
types.rs

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