use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Serialize, Deserialize)]
pub struct ApiResponse<T> {
pub msg: String,
pub code: u16,
pub state: String,
pub data: Option<T>,
}
impl<T> ApiResponse<T> {
pub fn into_result(self) -> Result<T, ApiError> {
if self.code != 200 || self.state != "success" {
return Err(ApiError::Api {
code: self.code,
state: self.state,
msg: self.msg,
});
}
self.data.ok_or(ApiError::EmptyData)
}
pub fn as_result(&self) -> Result<&T, ApiError> {
if self.code != 200 || self.state != "success" {
return Err(ApiError::Api {
code: self.code,
state: self.state.clone(),
msg: self.msg.clone(),
});
}
self.data.as_ref().ok_or(ApiError::EmptyData)
}
}
#[derive(Debug, Error)]
pub enum ApiError {
#[error("api error: code={code}, state={state}, msg={msg}")]
Api {
code: u16,
state: String,
msg: String,
},
#[error("no token")]
NoToken,
#[error("api returned success but data is null")]
EmptyData,
#[error("reqwest error: {0}")]
Reqwest(#[from] reqwest::Error),
#[error("{0} not found")]
NotFound(String),
#[error("{0}")]
GenericError(String),
}
pub type ApiResult<T> = Result<ApiResponse<T>, ApiError>;