use std::fmt::{Debug, Display, Formatter};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct BaseResponse<T> {
#[serde(flatten)]
pub raw_response: RawResponse,
pub data: Option<T>,
}
impl<T> BaseResponse<T> {
pub fn success(&self) -> bool {
self.raw_response.code == 0
}
pub fn code(&self) -> i32 {
self.raw_response.code
}
pub fn msg(&self) -> &str {
&self.raw_response.msg
}
pub fn err(&self) -> Option<&ErrorInfo> {
self.raw_response.err.as_ref()
}
}
pub trait ApiResponseTrait: for<'a> Deserialize<'a> + Send + Sync + 'static + Debug {
fn data_format() -> ResponseFormat;
fn from_binary(_file_name: String, _body: Vec<u8>) -> Option<Self> {
None
}
}
pub enum ResponseFormat {
Data,
Flatten,
Binary,
}
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct RawResponse {
pub code: i32,
pub msg: String,
#[serde(rename = "error", default, skip_serializing_if = "Option::is_none")]
pub err: Option<ErrorInfo>,
}
impl ApiResponseTrait for RawResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Flatten
}
}
impl Display for RawResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "code: {}, msg: {}", self.code, self.msg)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct EmptyResponse {}
impl ApiResponseTrait for EmptyResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
pub type JsonResponse = serde_json::Value;
impl ApiResponseTrait for JsonResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Data
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BinaryResponse {
pub file_name: String,
pub body: Vec<u8>,
}
impl ApiResponseTrait for BinaryResponse {
fn data_format() -> ResponseFormat {
ResponseFormat::Binary
}
fn from_binary(file_name: String, body: Vec<u8>) -> Option<Self> {
Some(BinaryResponse { file_name, body })
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ErrorInfo {
#[serde(rename = "key", default, skip_serializing_if = "Option::is_none")]
pub log_id: Option<String>,
#[serde(rename = "details", default, skip_serializing_if = "Vec::is_empty")]
pub details: Vec<CodeErrorDetail>,
#[serde(
rename = "permission_violations",
default,
skip_serializing_if = "Vec::is_empty"
)]
pub permission_violations: Vec<CodeErrorPermissionViolation>,
#[serde(
rename = "field_violations",
default,
skip_serializing_if = "Vec::is_empty"
)]
pub field_violations: Vec<CodeErrorFieldViolation>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CodeErrorDetail {
#[serde(rename = "key", default, skip_serializing_if = "Option::is_none")]
pub key: Option<String>,
#[serde(rename = "value", default, skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CodeErrorPermissionViolation {
#[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
pub type_: Option<String>,
#[serde(rename = "subject", default, skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
#[serde(
rename = "description",
default,
skip_serializing_if = "Option::is_none"
)]
pub description: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CodeErrorFieldViolation {
#[serde(rename = "field", default, skip_serializing_if = "Option::is_none")]
pub field: Option<String>,
#[serde(rename = "value", default, skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(
rename = "description",
default,
skip_serializing_if = "Option::is_none"
)]
pub description: Option<String>,
}