Skip to main content

trino_rust_client/models/
column.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use serde::de::{self, MapAccess, Visitor};
5use serde::ser::SerializeStruct;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8use super::RawTrinoTy;
9
10#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
11#[serde(rename_all = "camelCase")]
12pub struct Column {
13    pub name: String,
14    #[serde(rename = "type")]
15    pub ty: String,
16    pub type_signature: Option<TypeSignature>,
17}
18
19#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
20#[serde(rename_all = "camelCase")]
21pub struct TypeSignature {
22    pub raw_type: RawTrinoTy,
23    pub arguments: Vec<ClientTypeSignatureParameter>,
24    #[serde(skip)]
25    type_arguments: (), // deprecated
26    #[serde(skip)]
27    literal_arguments: (), //deprecated
28}
29
30#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
31#[serde(rename_all = "camelCase")]
32pub struct NamedTypeSignature {
33    pub field_name: Option<RowFieldName>,
34    pub type_signature: TypeSignature,
35}
36
37#[non_exhaustive]
38#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
39#[serde(rename_all = "camelCase")]
40pub struct RowFieldName {
41    pub name: String,
42}
43
44#[derive(Clone, Debug, Eq, PartialEq)]
45pub enum ClientTypeSignatureParameter {
46    TypeSignature(TypeSignature),
47    NamedTypeSignature(NamedTypeSignature),
48    LongLiteral(u64),
49}
50
51impl Serialize for ClientTypeSignatureParameter {
52    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
53    where
54        S: Serializer,
55    {
56        use ClientTypeSignatureParameter::*;
57        let mut state = serializer.serialize_struct("ClientTypeSignatureParameter", 2)?;
58        match self {
59            TypeSignature(s) => {
60                state.serialize_field("kind", "TYPE")?;
61                state.serialize_field("value", s)?;
62            }
63            NamedTypeSignature(s) => {
64                state.serialize_field("kind", "NAMED_TYPE")?;
65                state.serialize_field("value", s)?;
66            }
67            LongLiteral(s) => {
68                state.serialize_field("kind", "LONG")?;
69                state.serialize_field("value", s)?;
70            }
71        };
72        state.end()
73    }
74}
75
76impl<'de> Deserialize<'de> for ClientTypeSignatureParameter {
77    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
78    where
79        D: Deserializer<'de>,
80    {
81        #[derive(Deserialize)]
82        #[serde(field_identifier, rename_all = "lowercase")]
83        enum Field {
84            Kind,
85            Value,
86        }
87
88        struct ParamVisitor;
89
90        impl<'de> Visitor<'de> for ParamVisitor {
91            type Value = ClientTypeSignatureParameter;
92            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
93                formatter.write_str("struct ClientTypeSignatureParameter")
94            }
95
96            fn visit_map<V>(self, mut map: V) -> Result<ClientTypeSignatureParameter, V::Error>
97            where
98                V: MapAccess<'de>,
99            {
100                let kind = if let Some(Field::Kind) = map.next_key()? {
101                    // this is can't be `&str`
102                    // https://github.com/serde-rs/serde/issues/1009
103                    // https://github.com/serde-rs/serde/issues/1413#issuecomment-494892266
104                    map.next_value::<Cow<'_, str>>()?
105                } else {
106                    return Err(de::Error::missing_field("kind"));
107                };
108                if let Some(Field::Value) = map.next_key()? {
109                    match kind.as_ref() {
110                        "TYPE" | "TYPE_SIGNATURE" => {
111                            let v = map.next_value()?;
112                            Ok(ClientTypeSignatureParameter::TypeSignature(v))
113                        }
114                        "NAMED_TYPE" | "NAMED_TYPE_SIGNATURE" => {
115                            let v = map.next_value()?;
116                            Ok(ClientTypeSignatureParameter::NamedTypeSignature(v))
117                        }
118                        "LONG" | "LONG_LITERAL" => {
119                            let v = map.next_value()?;
120                            Ok(ClientTypeSignatureParameter::LongLiteral(v))
121                        }
122                        k => Err(de::Error::custom(format!("unknown kind: {}", k))),
123                    }
124                } else {
125                    Err(de::Error::missing_field("value"))
126                }
127            }
128        }
129
130        const FIELDS: &[&str] = &["kind", "value"];
131        deserializer.deserialize_struct("ClientTypeSignatureParameter", FIELDS, ParamVisitor)
132    }
133}
134
135impl TypeSignature {
136    pub fn new(raw_type: RawTrinoTy, arguments: Vec<ClientTypeSignatureParameter>) -> Self {
137        TypeSignature {
138            raw_type,
139            arguments,
140            type_arguments: (),
141            literal_arguments: (),
142        }
143    }
144}
145
146impl RowFieldName {
147    pub fn new(name: String) -> Self {
148        RowFieldName { name }
149    }
150}
151
152#[cfg(test)]
153mod tests {
154    use super::*;
155
156    #[test]
157    fn test_sig_varchar_de() {
158        let s = r#"
159        {
160                "rawType": "varchar",
161                "typeArguments": [],
162                "literalArguments": [],
163                "arguments": [
164                    {
165                        "kind": "LONG",
166                        "value": 2147483647
167                    }
168                ]
169        }
170        "#;
171
172        let s = serde_json::from_str::<TypeSignature>(s).unwrap();
173        assert_eq!(
174            s,
175            TypeSignature {
176                raw_type: RawTrinoTy::VarChar,
177                arguments: vec![ClientTypeSignatureParameter::LongLiteral(2147483647)],
178                type_arguments: (),
179                literal_arguments: (),
180            }
181        );
182    }
183
184    #[test]
185    fn test_sig_ty_de() {
186        let s = r#"
187        {
188                "rawType": "map",
189                "typeArguments": [],
190                "literalArguments": [],
191                "arguments": [
192                    {
193                        "kind": "TYPE_SIGNATURE",
194                        "value": {
195                            "rawType": "varchar",
196                            "typeArguments": [],
197                            "literalArguments": [],
198                            "arguments": [
199                                {
200                                    "kind": "LONG",
201                                    "value": 3
202                                }
203                            ]
204                        }
205                    }
206                ]
207            }
208        "#;
209
210        let s = serde_json::from_str::<TypeSignature>(s).unwrap();
211        assert_eq!(
212            s,
213            TypeSignature {
214                raw_type: RawTrinoTy::Map,
215                arguments: vec![ClientTypeSignatureParameter::TypeSignature(TypeSignature {
216                    raw_type: RawTrinoTy::VarChar,
217                    arguments: vec![ClientTypeSignatureParameter::LongLiteral(3)],
218                    type_arguments: (),
219                    literal_arguments: (),
220                })],
221                type_arguments: (),
222                literal_arguments: (),
223            }
224        );
225    }
226
227    #[test]
228    fn test_sig_named_ty_de() {
229        let s = r#"
230        {
231                "rawType": "row",
232                "typeArguments": [],
233                "literalArguments": [],
234                "arguments": [
235                    {
236                        "kind": "NAMED_TYPE_SIGNATURE",
237                        "value": {
238                            "fieldName": {
239                                "name": "y",
240                                "delimited": false
241                            },
242                            "typeSignature": {
243                                "rawType": "double",
244                                "typeArguments": [],
245                                "literalArguments": [],
246                                "arguments": []
247                            }
248                        }
249                    }
250                ]
251            }
252        "#;
253
254        let s = serde_json::from_str::<TypeSignature>(s).unwrap();
255        assert_eq!(
256            s,
257            TypeSignature {
258                raw_type: RawTrinoTy::Row,
259                arguments: vec![ClientTypeSignatureParameter::NamedTypeSignature(
260                    NamedTypeSignature {
261                        field_name: Some(RowFieldName {
262                            name: "y".to_string(),
263                        }),
264                        type_signature: TypeSignature {
265                            raw_type: RawTrinoTy::Double,
266                            arguments: vec![],
267                            type_arguments: (),
268                            literal_arguments: (),
269                        }
270                    }
271                )],
272                type_arguments: (),
273                literal_arguments: (),
274            }
275        );
276    }
277
278    #[test]
279    fn test_sig_param() {
280        let s = r#"{"kind":"LONG","value":10}"#;
281        let res = serde_json::from_str::<ClientTypeSignatureParameter>(s).unwrap();
282        assert_eq!(res, ClientTypeSignatureParameter::LongLiteral(10));
283
284        let json = serde_json::to_value(res.clone()).unwrap();
285        let res2: ClientTypeSignatureParameter = serde_json::from_value(json).unwrap();
286        assert_eq!(res, res2)
287    }
288}