1use crate::{Error, UptoboxResult};
2
3#[derive(serde::Deserialize)]
4#[serde(rename_all = "camelCase")]
5pub struct ErrorDeserialize {
6 pub status_code: usize,
7 pub message: String,
8 pub data: Option<String>,
9}
10
11pub fn deserialize<'de, T>(json: &'de str) -> UptoboxResult<T>
12where
13 T: serde::Deserialize<'de> + DeserializeCheck,
14{
15 match serde_json::from_str::<T>(json) {
16 Ok(r) => match r.status_code() {
17 0 | 16 | 39 => Ok(r),
18 _ => match serde_json::from_str::<ErrorDeserialize>(json) {
19 Ok(r) => Err(Error::ParseResponse(
20 r.status_code,
21 r.message,
22 r.data.unwrap_or_default(),
23 )),
24 Err(e) => Err(Error::UnknownParseResponse(e)),
25 },
26 },
27 Err(e) => match serde_json::from_str::<ErrorDeserialize>(json) {
28 Ok(r) => Err(Error::ParseResponse(
29 r.status_code,
30 r.message,
31 r.data.unwrap_or_default(),
32 )),
33 Err(_) => Err(Error::UnknownParseResponse(e)),
34 },
35 }
36}
37
38pub trait DeserializeCheck {
39 fn status_code(&self) -> usize;
40}