use serde::{Deserialize, Serialize};
use crate::error::ErrorMessage;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
pub struct Basic<T> {
pub data: Data<T>,
pub success: bool,
pub status: u16,
}
impl<T> From<Basic<T>> for Result<T, ErrorMessage> {
fn from(b: Basic<T>) -> Self {
b.data.into()
}
}
impl<T> Basic<T> {
pub fn result(self) -> Result<T, ErrorMessage> {
self.into()
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
#[serde(untagged)]
pub enum Data<T> {
Content(T),
Error {
error: ErrorMessage,
request: String,
method: Method,
},
}
impl<T> From<Data<T>> for Result<T, ErrorMessage> {
fn from(d: Data<T>) -> Self {
match d {
Data::Content(c) => Ok(c),
Data::Error {
error,
request: _,
method: _,
} => Err(error),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
#[serde(deny_unknown_fields)]
pub enum Method {
GET,
POST,
PUT,
DELETE,
}
#[cfg(test)]
mod test {
use std::error::Error;
use crate::model::{
account_settings::AccountSettings,
basic::{Basic, Data, ErrorMessage, Method},
};
#[test]
fn test_error_parsing_local() -> Result<(), Box<dyn Error>> {
let res = r#"{
"data": {
"error": "Authentication required",
"request": "/3/account/me/settings",
"method": "GET"
},
"success": false,
"status": 401
}"#;
let data = serde_json::from_str::<Basic<AccountSettings>>(res)?;
assert!(!data.success);
assert_eq!(data.status, 401);
match data.data {
Data::Content(_) => panic!("Should return error"),
Data::Error {
error,
request,
method,
} => {
assert_eq!(error, ErrorMessage::new("Authentication required"));
assert_eq!(request, "/3/account/me/settings");
assert_eq!(method, Method::GET);
}
}
Ok(())
}
}