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}
63
64impl fmt::Display for Value {
65 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66 match self {
67 Value::Number(v, l) => write!(f, "{}{long}", v, long = if *l { "L" } else { "" }),
68 Value::DoubleQuotedString(v) => write!(f, "\"{}\"", v),
69 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
70 Value::NationalStringLiteral(v) => write!(f, "N'{}'", v),
71 Value::HexStringLiteral(v) => write!(f, "X'{}'", v),
72 Value::Boolean(v) => write!(f, "{}", v),
73 Value::Interval {
74 value,
75 leading_field: Some(DateTimeField::Second),
76 leading_precision: Some(leading_precision),
77 last_field,
78 fractional_seconds_precision: Some(fractional_seconds_precision),
79 } => {
80 assert!(last_field.is_none());
83 write!(
84 f,
85 "INTERVAL '{}' SECOND ({}, {})",
86 escape_single_quote_string(value),
87 leading_precision,
88 fractional_seconds_precision
89 )
90 }
91 Value::Interval {
92 value,
93 leading_field,
94 leading_precision,
95 last_field,
96 fractional_seconds_precision,
97 } => {
98 write!(f, "INTERVAL '{}'", escape_single_quote_string(value))?;
99 if let Some(leading_field) = leading_field {
100 write!(f, " {}", leading_field)?;
101 }
102 if let Some(leading_precision) = leading_precision {
103 write!(f, " ({})", leading_precision)?;
104 }
105 if let Some(last_field) = last_field {
106 write!(f, " TO {}", last_field)?;
107 }
108 if let Some(fractional_seconds_precision) = fractional_seconds_precision {
109 write!(f, " ({})", fractional_seconds_precision)?;
110 }
111 Ok(())
112 }
113 Value::Null => write!(f, "NULL"),
114 }
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
119#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
120pub enum DateTimeField {
121 Year,
122 Month,
123 Day,
124 Hour,
125 Minute,
126 Second,
127}
128
129impl fmt::Display for DateTimeField {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 f.write_str(match self {
132 DateTimeField::Year => "YEAR",
133 DateTimeField::Month => "MONTH",
134 DateTimeField::Day => "DAY",
135 DateTimeField::Hour => "HOUR",
136 DateTimeField::Minute => "MINUTE",
137 DateTimeField::Second => "SECOND",
138 })
139 }
140}
141
142pub struct EscapeSingleQuoteString<'a>(&'a str);
143
144impl<'a> fmt::Display for EscapeSingleQuoteString<'a> {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 for c in self.0.chars() {
147 if c == '\'' {
148 write!(f, "\'\'")?;
149 } else {
150 write!(f, "{}", c)?;
151 }
152 }
153 Ok(())
154 }
155}
156
157pub fn escape_single_quote_string(s: &str) -> EscapeSingleQuoteString<'_> {
158 EscapeSingleQuoteString(s)
159}
160
161#[derive(Debug, Clone, PartialEq, Eq, Hash)]
162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
163pub enum TrimWhereField {
164 Both,
165 Leading,
166 Trailing,
167}
168
169impl fmt::Display for TrimWhereField {
170 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171 use TrimWhereField::*;
172 f.write_str(match self {
173 Both => "BOTH",
174 Leading => "LEADING",
175 Trailing => "TRAILING",
176 })
177 }
178}