1use std::fmt::Display;
16
17use common_macro::stack_trace_debug;
18use snafu::{Location, Snafu};
19use sql::ast::Value;
20
21#[derive(Snafu)]
22#[snafu(visibility(pub))]
23#[stack_trace_debug]
24pub enum Error {
25 #[snafu(display("Invalid value for parameter \"{}\": {}\nHint: {}", name, value, hint,))]
26 InvalidConfigValue {
27 name: String,
28 value: String,
29 hint: String,
30 #[snafu(implicit)]
31 location: Location,
32 },
33}
34
35#[derive(Clone, Copy, Debug, Default)]
36pub enum PGByteaOutputValue {
37 #[default]
38 HEX,
39 ESCAPE,
40}
41
42impl TryFrom<Value> for PGByteaOutputValue {
43 type Error = Error;
44
45 fn try_from(value: Value) -> Result<Self, Self::Error> {
46 match &value {
47 Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
48 match s.to_uppercase().as_str() {
49 "ESCAPE" => Ok(PGByteaOutputValue::ESCAPE),
50 "HEX" => Ok(PGByteaOutputValue::HEX),
51 _ => InvalidConfigValueSnafu {
52 name: "BYTEA_OUTPUT",
53 value: value.to_string(),
54 hint: "Available values: escape, hex",
55 }
56 .fail(),
57 }
58 }
59 _ => InvalidConfigValueSnafu {
60 name: "BYTEA_OUTPUT",
61 value: value.to_string(),
62 hint: "Available values: escape, hex",
63 }
64 .fail(),
65 }
66 }
67}
68
69impl Display for PGByteaOutputValue {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 match self {
72 PGByteaOutputValue::HEX => write!(f, "hex"),
73 PGByteaOutputValue::ESCAPE => write!(f, "escape"),
74 }
75 }
76}
77
78#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
80pub enum PGDateOrder {
81 #[default]
82 MDY,
83 DMY,
84 YMD,
85}
86
87impl Display for PGDateOrder {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 match self {
90 PGDateOrder::MDY => write!(f, "MDY"),
91 PGDateOrder::DMY => write!(f, "DMY"),
92 PGDateOrder::YMD => write!(f, "YMD"),
93 }
94 }
95}
96
97impl TryFrom<&str> for PGDateOrder {
98 type Error = Error;
99
100 fn try_from(s: &str) -> Result<Self, Self::Error> {
101 match s.to_uppercase().as_str() {
102 "US" | "NONEURO" | "NONEUROPEAN" | "MDY" => Ok(PGDateOrder::MDY),
103 "EUROPEAN" | "EURO" | "DMY" => Ok(PGDateOrder::DMY),
104 "YMD" => Ok(PGDateOrder::YMD),
105 _ => InvalidConfigValueSnafu {
106 name: "DateStyle",
107 value: s,
108 hint: format!("Unrecognized key word: {}", s),
109 }
110 .fail(),
111 }
112 }
113}
114impl TryFrom<&Value> for PGDateOrder {
115 type Error = Error;
116
117 fn try_from(value: &Value) -> Result<Self, Self::Error> {
118 match value {
119 Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
120 Self::try_from(s.as_str())
121 }
122 _ => InvalidConfigValueSnafu {
123 name: "DateStyle",
124 value: value.to_string(),
125 hint: format!("Unrecognized key word: {}", value),
126 }
127 .fail(),
128 }
129 }
130}
131
132#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
133pub enum PGDateTimeStyle {
134 #[default]
135 ISO,
136 SQL,
137 Postgres,
138 German,
139}
140
141impl Display for PGDateTimeStyle {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 match self {
144 PGDateTimeStyle::ISO => write!(f, "ISO"),
145 PGDateTimeStyle::SQL => write!(f, "SQL"),
146 PGDateTimeStyle::Postgres => write!(f, "Postgres"),
147 PGDateTimeStyle::German => write!(f, "German"),
148 }
149 }
150}
151
152impl TryFrom<&str> for PGDateTimeStyle {
153 type Error = Error;
154
155 fn try_from(s: &str) -> Result<Self, Self::Error> {
156 match s.to_uppercase().as_str() {
157 "ISO" => Ok(PGDateTimeStyle::ISO),
158 "SQL" => Ok(PGDateTimeStyle::SQL),
159 "POSTGRES" => Ok(PGDateTimeStyle::Postgres),
160 "GERMAN" => Ok(PGDateTimeStyle::German),
161 _ => InvalidConfigValueSnafu {
162 name: "DateStyle",
163 value: s,
164 hint: format!("Unrecognized key word: {}", s),
165 }
166 .fail(),
167 }
168 }
169}
170
171impl TryFrom<&Value> for PGDateTimeStyle {
172 type Error = Error;
173
174 fn try_from(value: &Value) -> Result<Self, Self::Error> {
175 match value {
176 Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
177 Self::try_from(s.as_str())
178 }
179 _ => InvalidConfigValueSnafu {
180 name: "DateStyle",
181 value: value.to_string(),
182 hint: format!("Unrecognized key word: {}", value),
183 }
184 .fail(),
185 }
186 }
187}
188
189#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
190pub enum PGIntervalStyle {
191 ISO,
192 SQL,
193 #[default]
194 Postgres,
195 PostgresVerbose,
196}
197
198impl Display for PGIntervalStyle {
199 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200 match self {
201 PGIntervalStyle::ISO => write!(f, "iso_8601"),
202 PGIntervalStyle::SQL => write!(f, "sql_standard"),
203 PGIntervalStyle::Postgres => write!(f, "postgres"),
204 PGIntervalStyle::PostgresVerbose => write!(f, "postgres_verbose"),
205 }
206 }
207}
208
209impl TryFrom<&str> for PGIntervalStyle {
210 type Error = Error;
211
212 fn try_from(s: &str) -> Result<Self, Self::Error> {
213 match s.to_uppercase().as_str() {
214 "ISO" | "ISO_8601" => Ok(PGIntervalStyle::ISO),
215 "SQL" | "SQL_STANDARD" => Ok(PGIntervalStyle::SQL),
216 "POSTGRES" => Ok(PGIntervalStyle::Postgres),
217 "POSTGRES_VERBOSE" | "POSTGRES, VERBOSE" => Ok(PGIntervalStyle::PostgresVerbose),
218 _ => InvalidConfigValueSnafu {
219 name: "IntervalStyle",
220 value: s,
221 hint: format!("Unrecognized key word: {}", s),
222 }
223 .fail(),
224 }
225 }
226}
227
228impl TryFrom<&Value> for PGIntervalStyle {
229 type Error = Error;
230
231 fn try_from(value: &Value) -> Result<Self, Self::Error> {
232 match value {
233 Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
234 Self::try_from(s.as_str())
235 }
236 _ => InvalidConfigValueSnafu {
237 name: "IntervalStyle",
238 value: value.to_string(),
239 hint: format!("Unrecognized key word: {}", value),
240 }
241 .fail(),
242 }
243 }
244}