1#[cfg(not(feature = "std"))]
14use alloc::string::String;
15use core::fmt;
16
17#[cfg(feature = "bigdecimal")]
18use bigdecimal::BigDecimal;
19#[cfg(feature = "serde")]
20use serde::{Deserialize, Serialize};
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub enum Value {
26 #[cfg(not(feature = "bigdecimal"))]
28 Number(String, bool),
29 #[cfg(feature = "bigdecimal")]
30 Number(BigDecimal, bool),
31 SingleQuotedString(String),
33 NationalStringLiteral(String),
35 HexStringLiteral(String),
37
38 DoubleQuotedString(String),
39 Boolean(bool),
41 Interval {
50 value: String,
51 leading_field: Option<DateTimeField>,
52 leading_precision: Option<u64>,
53 last_field: Option<DateTimeField>,
54 fractional_seconds_precision: Option<u64>,
59 },
60 Null,
62 Placeholder(String),
64}
65
66impl fmt::Display for Value {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 match self {
69 Value::Number(v, l) => write!(f, "{}{long}", v, long = if *l { "L" } else { "" }),
70 Value::DoubleQuotedString(v) => write!(f, "\"{}\"", v),
71 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
72 Value::NationalStringLiteral(v) => write!(f, "N'{}'", v),
73 Value::HexStringLiteral(v) => write!(f, "X'{}'", v),
74 Value::Boolean(v) => write!(f, "{}", v),
75 Value::Interval {
76 value,
77 leading_field: Some(DateTimeField::Second),
78 leading_precision: Some(leading_precision),
79 last_field,
80 fractional_seconds_precision: Some(fractional_seconds_precision),
81 } => {
82 assert!(last_field.is_none());
85 write!(
86 f,
87 "INTERVAL '{}' SECOND ({}, {})",
88 escape_single_quote_string(value),
89 leading_precision,
90 fractional_seconds_precision
91 )
92 }
93 Value::Interval {
94 value,
95 leading_field,
96 leading_precision,
97 last_field,
98 fractional_seconds_precision,
99 } => {
100 write!(f, "INTERVAL '{}'", escape_single_quote_string(value))?;
101 if let Some(leading_field) = leading_field {
102 write!(f, " {}", leading_field)?;
103 }
104 if let Some(leading_precision) = leading_precision {
105 write!(f, " ({})", leading_precision)?;
106 }
107 if let Some(last_field) = last_field {
108 write!(f, " TO {}", last_field)?;
109 }
110 if let Some(fractional_seconds_precision) = fractional_seconds_precision {
111 write!(f, " ({})", fractional_seconds_precision)?;
112 }
113 Ok(())
114 }
115 Value::Null => write!(f, "NULL"),
116 Value::Placeholder(v) => write!(f, "{}", v),
117 }
118 }
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, Hash)]
122#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
123pub enum DateTimeField {
124 Year,
125 Month,
126 Day,
127 Hour,
128 Minute,
129 Second,
130}
131
132impl fmt::Display for DateTimeField {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 f.write_str(match self {
135 DateTimeField::Year => "YEAR",
136 DateTimeField::Month => "MONTH",
137 DateTimeField::Day => "DAY",
138 DateTimeField::Hour => "HOUR",
139 DateTimeField::Minute => "MINUTE",
140 DateTimeField::Second => "SECOND",
141 })
142 }
143}
144
145pub struct EscapeSingleQuoteString<'a>(&'a str);
146
147impl<'a> fmt::Display for EscapeSingleQuoteString<'a> {
148 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
149 for c in self.0.chars() {
150 if c == '\'' {
151 write!(f, "\'\'")?;
152 } else {
153 write!(f, "{}", c)?;
154 }
155 }
156 Ok(())
157 }
158}
159
160pub fn escape_single_quote_string(s: &str) -> EscapeSingleQuoteString<'_> {
161 EscapeSingleQuoteString(s)
162}
163
164#[derive(Debug, Clone, PartialEq, Eq, Hash)]
165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
166pub enum TrimWhereField {
167 Both,
168 Leading,
169 Trailing,
170}
171
172impl fmt::Display for TrimWhereField {
173 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174 use TrimWhereField::*;
175 f.write_str(match self {
176 Both => "BOTH",
177 Leading => "LEADING",
178 Trailing => "TRAILING",
179 })
180 }
181}