1use std::ops::Deref;
11
12use log::trace;
13use serde::{
14 de::{self, DeserializeOwned, Deserializer},
15 Deserialize,
16};
17use serde_json::value::Value;
18
19use crate::{ArangoError, ClientError};
20
21pub(crate) fn deserialize_response<T>(text: &str) -> Result<T, ClientError>
29where
30 T: DeserializeOwned,
31{
32 let response: Response<T> = serde_json::from_str(text)?;
33 Ok(Into::<Result<T, ArangoError>>::into(response)?)
34}
35
36#[derive(Debug)]
47pub(crate) enum Response<T> {
48 Ok(T),
49 Err(ArangoError),
50}
51
52impl<T> From<Response<T>> for Result<T, ArangoError> {
53 fn from(resp: Response<T>) -> Self {
54 match resp {
55 Response::Ok(success) => Ok(success),
56 Response::Err(err) => Err(err),
57 }
58 }
59}
60
61impl<'de, T> Deserialize<'de> for Response<T>
62where
63 T: Deserialize<'de>,
64{
65 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66 where
67 D: Deserializer<'de>,
68 {
69 let map = serde_json::Map::deserialize(deserializer)?;
70 trace!("Deserialize normal Response: {:?}", map);
71 let error = map
72 .get("error")
73 .map_or_else(|| Ok(false), Deserialize::deserialize)
74 .map_err(de::Error::custom)?;
75 let rest = Value::Object(map);
76
77 if error {
78 ArangoError::deserialize(rest)
79 .map(Response::Err)
80 .map_err(de::Error::custom)
81 } else {
82 T::deserialize(rest)
83 .map(Response::Ok)
84 .map_err(de::Error::custom)
85 }
86 }
87}
88
89#[derive(Deserialize, Debug)]
92pub(crate) struct ArangoResult<T> {
93 #[serde(rename = "result")]
94 result: T,
95}
96
97impl<T> ArangoResult<T> {
98 pub fn unwrap(self) -> T {
99 self.result
100 }
101}
102
103impl<T> Deref for ArangoResult<T> {
104 type Target = T;
105 fn deref(&self) -> &Self::Target {
106 &self.result
107 }
108}
109
110#[cfg(test)]
111mod test {
112 use super::*;
113
114 #[derive(Debug, Deserialize)]
115 pub struct CollectionResponse {
116 pub id: String,
117 pub name: String,
118 pub status: u8,
119 pub r#type: u8,
120 #[serde(rename = "isSystem")]
121 pub is_system: bool,
122 }
123
124 #[test]
125 fn response() {
126 let text = "{\"id\":\"9947\",\"name\":\"relation\",\"status\":2,\"type\":3,\"isSystem\": \
127 false,\"globallyUniqueId\":\"hD260BE2A30F9/9947\"}";
128 let result = serde_json::from_str::<Response<CollectionResponse>>(text);
129 assert_eq!(result.is_ok(), true, "failed: {:?}", result);
130
131 let text = "{\"error\":false,\"code\":412,\"id\":\"9947\",\"name\":\"relation\",\"status\"\
132 :2,\"type\":3,\"isSystem\": false,\"globallyUniqueId\":\"hD260BE2A30F9/9947\"}";
133 let result = serde_json::from_str::<Response<CollectionResponse>>(text);
134 assert_eq!(result.is_ok(), true, "failed: {:?}", result);
135
136 let text = "{\"error\":true,\"code\":412,\"errorMessage\":\"error\",\"errorNum\":1200}";
137 let result = serde_json::from_str::<Response<CollectionResponse>>(text);
138 assert_eq!(result.is_ok(), true, "failed: {:?}", result);
139 let response = Into::<Result<_, _>>::into(result.unwrap());
140
141 assert_eq!(
142 response.is_err(),
143 true,
144 "response should be error: {:?}",
145 response
146 );
147 }
148}