1#[cfg(feature = "bigdecimal")]
14use bigdecimal::BigDecimal;
15use std::fmt;
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19pub enum Value {
20 #[cfg(not(feature = "bigdecimal"))]
22 Number(String),
23 #[cfg(feature = "bigdecimal")]
24 Number(BigDecimal),
25 SingleQuotedString(String),
27 NationalStringLiteral(String),
29 HexStringLiteral(String),
31 Boolean(bool),
33 Date(String),
35 Time(String),
37 Timestamp(String),
39 Interval {
48 value: String,
49 leading_field: DateTimeField,
50 leading_precision: Option<u64>,
51 last_field: Option<DateTimeField>,
52 fractional_seconds_precision: Option<u64>,
57 },
58 Null,
60 Default,
62}
63
64impl fmt::Display for Value {
65 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66 match self {
67 Value::Number(v) => write!(f, "{}", v),
68 Value::SingleQuotedString(v) => write!(f, "'{}'", escape_single_quote_string(v)),
69 Value::NationalStringLiteral(v) => write!(f, "N'{}'", v),
70 Value::HexStringLiteral(v) => write!(f, "X'{}'", v),
71 Value::Boolean(v) => write!(f, "{}", v),
72 Value::Date(v) => write!(f, "DATE '{}'", escape_single_quote_string(v)),
73 Value::Time(v) => write!(f, "TIME '{}'", escape_single_quote_string(v)),
74 Value::Timestamp(v) => write!(f, "TIMESTAMP '{}'", escape_single_quote_string(v)),
75 Value::Interval {
76 value,
77 leading_field: 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!(
101 f,
102 "INTERVAL '{}' {}",
103 escape_single_quote_string(value),
104 leading_field
105 )?;
106 if let Some(leading_precision) = leading_precision {
107 write!(f, " ({})", leading_precision)?;
108 }
109 if let Some(last_field) = last_field {
110 write!(f, " TO {}", last_field)?;
111 }
112 if let Some(fractional_seconds_precision) = fractional_seconds_precision {
113 write!(f, " ({})", fractional_seconds_precision)?;
114 }
115 Ok(())
116 }
117 Value::Null => write!(f, "NULL"),
118 Value::Default => write!(f, "DEFAULT"),
119 }
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
124pub enum DateTimeField {
125 Year,
126 Month,
127 Day,
128 Hour,
129 Minute,
130 Second,
131}
132
133impl fmt::Display for DateTimeField {
134 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135 f.write_str(match self {
136 DateTimeField::Year => "YEAR",
137 DateTimeField::Month => "MONTH",
138 DateTimeField::Day => "DAY",
139 DateTimeField::Hour => "HOUR",
140 DateTimeField::Minute => "MINUTE",
141 DateTimeField::Second => "SECOND",
142 })
143 }
144}
145
146pub struct EscapeSingleQuoteString<'a>(&'a str);
147
148impl<'a> fmt::Display for EscapeSingleQuoteString<'a> {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 for c in self.0.chars() {
151 if c == '\'' {
152 write!(f, "\'\'")?;
153 } else {
154 write!(f, "{}", c)?;
155 }
156 }
157 Ok(())
158 }
159}
160
161pub fn escape_single_quote_string(s: &str) -> EscapeSingleQuoteString<'_> {
162 EscapeSingleQuoteString(s)
163}