qail_core/ast/
values.rs

1use serde::{Deserialize, Serialize};
2use uuid::Uuid;
3use crate::ast::QailCmd;
4
5/// Time interval unit for duration expressions
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub enum IntervalUnit {
8    Second,
9    Minute,
10    Hour,
11    Day,
12    Week,
13    Month,
14    Year,
15}
16
17impl std::fmt::Display for IntervalUnit {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            IntervalUnit::Second => write!(f, "seconds"),
21            IntervalUnit::Minute => write!(f, "minutes"),
22            IntervalUnit::Hour => write!(f, "hours"),
23            IntervalUnit::Day => write!(f, "days"),
24            IntervalUnit::Week => write!(f, "weeks"),
25            IntervalUnit::Month => write!(f, "months"),
26            IntervalUnit::Year => write!(f, "years"),
27        }
28    }
29}
30
31/// A value in a condition.
32#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
33pub enum Value {
34    /// NULL value
35    Null,
36    /// Boolean
37    Bool(bool),
38    /// Integer
39    Int(i64),
40    /// Float
41    Float(f64),
42    /// String
43    String(String),
44    /// Parameter reference ($1, $2, etc.)
45    Param(usize),
46    /// Named parameter reference (:name, :id, etc.)
47    NamedParam(String),
48    /// SQL function call (e.g., now())
49    Function(String),
50    /// Array of values
51    Array(Vec<Value>),
52    /// Subquery for IN/EXISTS expressions (e.g., WHERE id IN (SELECT ...))
53    Subquery(Box<QailCmd>),
54    /// Column reference (e.g. JOIN ... ON a.id = b.id)
55    Column(String),
56    /// UUID value
57    Uuid(Uuid),
58    /// Null UUID value (for typed NULL in UUID columns)
59    NullUuid,
60    /// Time interval (e.g., 24 hours, 7 days)
61    Interval { amount: i64, unit: IntervalUnit },
62    /// Timestamp value (for DateTime binding)
63    Timestamp(String),
64}
65
66impl std::fmt::Display for Value {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        match self {
69            Value::Null => write!(f, "NULL"),
70            Value::Bool(b) => write!(f, "{}", b),
71            Value::Int(n) => write!(f, "{}", n),
72            Value::Float(n) => write!(f, "{}", n),
73            Value::String(s) => write!(f, "'{}'", s),
74            Value::Param(n) => write!(f, "${}", n),
75            Value::NamedParam(name) => write!(f, ":{}", name),
76            Value::Function(s) => write!(f, "{}", s),
77            Value::Array(arr) => {
78                write!(f, "(")?;
79                for (i, v) in arr.iter().enumerate() {
80                    if i > 0 { write!(f, ", ")?; }
81                    write!(f, "{}", v)?;
82                }
83                write!(f, ")")
84            },
85            Value::Subquery(_) => write!(f, "(SUBQUERY)"),
86            Value::Column(s) => write!(f, "{}", s),
87            Value::Uuid(u) => write!(f, "'{}'", u),
88            Value::NullUuid => write!(f, "NULL"),
89            Value::Interval { amount, unit } => write!(f, "INTERVAL '{} {}'", amount, unit),
90            Value::Timestamp(ts) => write!(f, "'{}'", ts),
91        }
92    }
93}
94
95impl From<bool> for Value {
96    fn from(b: bool) -> Self {
97        Value::Bool(b)
98    }
99}
100
101impl From<i32> for Value {
102    fn from(n: i32) -> Self {
103        Value::Int(n as i64)
104    }
105}
106
107impl From<i64> for Value {
108    fn from(n: i64) -> Self {
109        Value::Int(n)
110    }
111}
112
113impl From<f64> for Value {
114    fn from(n: f64) -> Self {
115        Value::Float(n)
116    }
117}
118
119impl From<&str> for Value {
120    fn from(s: &str) -> Self {
121        Value::String(s.to_string())
122    }
123}
124
125impl From<String> for Value {
126    fn from(s: String) -> Self {
127        Value::String(s)
128    }
129}
130
131
132impl From<Uuid> for Value {
133    fn from(u: Uuid) -> Self {
134        Value::Uuid(u)
135    }
136}
137
138impl From<Option<Uuid>> for Value {
139    fn from(opt: Option<Uuid>) -> Self {
140        match opt {
141            Some(u) => Value::Uuid(u),
142            None => Value::NullUuid,
143        }
144    }
145}