google_cloud_bigquery/http/
mod.rs1use std::fmt::Display;
2use std::str::FromStr;
3
4use serde::{de, Deserialize, Deserializer};
5use serde_json::Value;
6
7pub mod bigquery_client;
8pub mod bigquery_dataset_client;
9pub mod bigquery_job_client;
10pub mod bigquery_model_client;
11pub mod bigquery_routine_client;
12pub mod bigquery_row_access_policy_client;
13pub mod bigquery_table_client;
14pub mod bigquery_tabledata_client;
15pub mod dataset;
16pub mod error;
17pub mod job;
18pub mod model;
19pub mod query;
20pub mod routine;
21pub mod row_access_policy;
22pub mod table;
23pub mod tabledata;
24pub mod types;
25
26fn from_str_option<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
27where
28 T: FromStr,
29 T::Err: Display,
30 D: Deserializer<'de>,
31{
32 let s: Result<Value, _> = Deserialize::deserialize(deserializer);
33 match s {
34 Ok(Value::String(s)) => T::from_str(&s).map_err(de::Error::custom).map(Some),
35 Ok(_) => Err(de::Error::custom("Incorrect type")),
36 Err(_) => Ok(None),
37 }
38}
39
40pub fn from_str<'de, T, D>(deserializer: D) -> Result<T, D::Error>
41where
42 T: FromStr,
43 T::Err: Display,
44 D: de::Deserializer<'de>,
45{
46 let s = String::deserialize(deserializer)?;
47 T::from_str(&s).map_err(de::Error::custom)
48}
49
50fn into_str<T, S>(value: T, s: S) -> Result<S::Ok, S::Error>
51where
52 T: ToString,
53 S: serde::Serializer,
54{
55 s.serialize_str(&value.to_string())
56}
57
58fn from_str_vec_option<'de, T, D>(deserializer: D) -> Result<Option<Vec<T>>, D::Error>
59where
60 T: FromStr,
61 T::Err: Display,
62 D: Deserializer<'de>,
63{
64 let s: Result<Value, _> = Deserialize::deserialize(deserializer);
65 match s {
66 Ok(Value::Array(vec)) => {
67 let mut result = Vec::with_capacity(vec.len());
68 for v in vec {
69 let v = match v {
70 Value::String(s) => T::from_str(&s).map_err(de::Error::custom)?,
71 _ => return Err(de::Error::custom("Incorrect type")),
72 };
73 result.push(v);
74 }
75 Ok(Some(result))
76 }
77 Ok(_) => Err(de::Error::custom("Incorrect type")),
78 Err(_) => Ok(None),
79 }
80}
81
82fn from_str_vec<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
83where
84 T: FromStr,
85 T::Err: Display,
86 D: Deserializer<'de>,
87{
88 let vec: Vec<String> = Vec::deserialize(deserializer)?;
89 let mut result = Vec::with_capacity(vec.len());
90 for v in vec {
91 result.push(T::from_str(&v).map_err(de::Error::custom)?);
92 }
93 Ok(result)
94}
95
96#[cfg(test)]
97mod test {
98
99 #[derive(Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, Debug, Default)]
100 #[serde(rename_all = "camelCase")]
101 struct Test {
102 #[serde(default, deserialize_with = "crate::http::from_str_vec_option")]
103 pub field: Option<Vec<i64>>,
104 }
105
106 #[test]
107 fn test_from_str_vec_option() {
108 let value: Test = serde_json::from_str(r#"{"field": ["100", "200"]}"#).unwrap();
109 let record = value.field.unwrap();
110 assert_eq!(vec![100, 200], record);
111
112 let value: Test = serde_json::from_str(r#"{}"#).unwrap();
113 assert!(value.field.is_none());
114 }
115
116 #[derive(Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, Debug, Default)]
117 #[serde(rename_all = "camelCase")]
118 struct Test2 {
119 #[serde(deserialize_with = "crate::http::from_str_vec")]
120 pub field: Vec<i64>,
121 }
122
123 #[test]
124 fn test_from_str_vec() {
125 let value: Test2 = serde_json::from_str(r#"{"field": ["100", "200"]}"#).unwrap();
126 assert_eq!(vec![100, 200], value.field);
127 let result = serde_json::from_str::<Test2>(r#"{}"#);
128 assert!(result.is_err())
129 }
130}