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
69#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
71pub enum PGDateOrder {
72 #[default]
73 MDY,
74 DMY,
75 YMD,
76}
77
78impl Display for PGDateOrder {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 match self {
81 PGDateOrder::MDY => write!(f, "MDY"),
82 PGDateOrder::DMY => write!(f, "DMY"),
83 PGDateOrder::YMD => write!(f, "YMD"),
84 }
85 }
86}
87
88impl TryFrom<&str> for PGDateOrder {
89 type Error = Error;
90
91 fn try_from(s: &str) -> Result<Self, Self::Error> {
92 match s.to_uppercase().as_str() {
93 "US" | "NONEURO" | "NONEUROPEAN" | "MDY" => Ok(PGDateOrder::MDY),
94 "EUROPEAN" | "EURO" | "DMY" => Ok(PGDateOrder::DMY),
95 "YMD" => Ok(PGDateOrder::YMD),
96 _ => InvalidConfigValueSnafu {
97 name: "DateStyle",
98 value: s,
99 hint: format!("Unrecognized key word: {}", s),
100 }
101 .fail(),
102 }
103 }
104}
105impl TryFrom<&Value> for PGDateOrder {
106 type Error = Error;
107
108 fn try_from(value: &Value) -> Result<Self, Self::Error> {
109 match value {
110 Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
111 Self::try_from(s.as_str())
112 }
113 _ => InvalidConfigValueSnafu {
114 name: "DateStyle",
115 value: value.to_string(),
116 hint: format!("Unrecognized key word: {}", value),
117 }
118 .fail(),
119 }
120 }
121}
122
123#[derive(Default, PartialEq, Eq, Clone, Copy, Debug)]
124pub enum PGDateTimeStyle {
125 #[default]
126 ISO,
127 SQL,
128 Postgres,
129 German,
130}
131
132impl Display for PGDateTimeStyle {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 match self {
135 PGDateTimeStyle::ISO => write!(f, "ISO"),
136 PGDateTimeStyle::SQL => write!(f, "SQL"),
137 PGDateTimeStyle::Postgres => write!(f, "Postgres"),
138 PGDateTimeStyle::German => write!(f, "German"),
139 }
140 }
141}
142
143impl TryFrom<&str> for PGDateTimeStyle {
144 type Error = Error;
145
146 fn try_from(s: &str) -> Result<Self, Self::Error> {
147 match s.to_uppercase().as_str() {
148 "ISO" => Ok(PGDateTimeStyle::ISO),
149 "SQL" => Ok(PGDateTimeStyle::SQL),
150 "POSTGRES" => Ok(PGDateTimeStyle::Postgres),
151 "GERMAN" => Ok(PGDateTimeStyle::German),
152 _ => InvalidConfigValueSnafu {
153 name: "DateStyle",
154 value: s,
155 hint: format!("Unrecognized key word: {}", s),
156 }
157 .fail(),
158 }
159 }
160}
161
162impl TryFrom<&Value> for PGDateTimeStyle {
163 type Error = Error;
164
165 fn try_from(value: &Value) -> Result<Self, Self::Error> {
166 match value {
167 Value::DoubleQuotedString(s) | Value::SingleQuotedString(s) => {
168 Self::try_from(s.as_str())
169 }
170 _ => InvalidConfigValueSnafu {
171 name: "DateStyle",
172 value: value.to_string(),
173 hint: format!("Unrecognized key word: {}", value),
174 }
175 .fail(),
176 }
177 }
178}