#![deny(non_ascii_idents)]
#![allow(clippy::disallowed_names)]
#![allow(clippy::blanket_clippy_restriction_lints)]
#![warn(clippy::missing_panics_doc)]
#![warn(clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated)]
#![warn(clippy::missing_const_for_fn)]
#![warn(
clippy::cast_lossless,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::ptr_as_ptr
)]
#![warn(clippy::many_single_char_names)]
#![warn(clippy::default_numeric_fallback)]
#![warn(clippy::checked_conversions)]
#![warn(clippy::match_bool)]
#![warn(clippy::needless_bitwise_bool)]
#![deny(clippy::cast_sign_loss)]
#![warn(clippy::modulo_arithmetic)]
#![warn(clippy::cast_precision_loss)]
#![warn(clippy::float_arithmetic, clippy::float_cmp, clippy::float_cmp_const)]
#![warn(clippy::imprecise_flops, clippy::suboptimal_flops)]
#![warn(clippy::large_stack_arrays)]
#![warn(clippy::exhaustive_structs)]
#![warn(clippy::exhaustive_enums)]
#![warn(clippy::struct_excessive_bools)]
#![warn(clippy::fn_params_excessive_bools)]
#![warn(clippy::enum_glob_use)]
#![warn(clippy::else_if_without_else)]
#![warn(clippy::string_add_assign, clippy::string_add)]
#![warn(clippy::string_lit_as_bytes)]
#![warn(clippy::string_slice)]
#![warn(clippy::large_types_passed_by_value)]
#![warn(clippy::trivially_copy_pass_by_ref)]
#![warn(clippy::inefficient_to_string)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::copy_iterator)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::unwrap_used)]
#![warn(clippy::wildcard_imports)]
#![warn(clippy::self_named_module_files)]
#![warn(clippy::cargo_common_metadata)]
#![warn(clippy::negative_feature_names, clippy::redundant_feature_names)]
#![warn(clippy::wildcard_dependencies)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::await_holding_lock)]
#![warn(clippy::await_holding_refcell_ref)]
#![warn(clippy::unused_async)]
#![warn(clippy::debug_assert_with_mut_call)]
#![cfg_attr(feature = "try", feature(try_trait_v2))]
#[cfg(feature = "try")]
mod try_trait;
#[cfg(feature = "salvo")]
mod salvo_trait;
mod error;
pub mod error_code;
#[cfg(feature = "lite")]
pub(crate) mod lite;
mod meta;
mod result;
mod success;
mod utils;
use std::{error::Error, fmt::Debug};
pub use prelude::*;
pub mod prelude {
pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
pub use crate::{
ApiResponse, api_err,
error::{ApiError, ErrorResponse},
error_code,
error_code::ety_grpc,
meta::{Cost, DefaultMeta, Pagination, RateLimit, UserMeta},
result::ApiResult,
success::{ApiSuccessResponse, SuccessResponse},
utils::{ErrWrapper, IntoError, MaybeString},
};
}
#[cfg_attr(not(feature = "lite"), derive(Serialize, Deserialize))]
#[cfg_attr(not(feature = "lite"), serde(tag = "status", rename_all = "lowercase"))]
#[derive(Debug)]
#[allow(clippy::exhaustive_enums)]
pub enum ApiResponse<Data, Meta> {
Success(SuccessResponse<Data, Meta>),
Error(ErrorResponse<Meta>),
}
impl<Data, Meta> From<SuccessResponse<Data, Meta>> for ApiResponse<Data, Meta> {
fn from(value: SuccessResponse<Data, Meta>) -> Self {
Self::Success(value)
}
}
impl<Data, Meta> From<ErrorResponse<Meta>> for ApiResponse<Data, Meta> {
fn from(value: ErrorResponse<Meta>) -> Self {
Self::Error(value)
}
}
impl<Data, Meta> From<ApiError> for ApiResponse<Data, Meta> {
fn from(error: ApiError) -> Self {
ApiResponse::Error(ErrorResponse::from_error(error))
}
}
impl<Data, Meta> ApiResponse<Data, Meta> {
#[inline(always)]
pub const fn new_success(data: Data, meta: Meta) -> Self {
Self::Success(SuccessResponse::new(data, meta))
}
#[inline(always)]
pub const fn from_success(data: Data) -> Self {
Self::Success(SuccessResponse::from_data(data))
}
#[inline(always)]
pub const fn from_success_data(data: Data) -> Self {
Self::Success(SuccessResponse::from_data(data))
}
#[inline(always)]
pub const fn new_error(error: ApiError, meta: Meta) -> Self {
Self::Error(ErrorResponse::new(error, meta))
}
#[inline(always)]
pub const fn from_error(error: ApiError) -> Self {
Self::Error(ErrorResponse::from_error(error))
}
#[inline(always)]
pub fn from_error_msg(code: impl Into<u32>, message: impl Into<String>) -> Self {
Self::Error(ErrorResponse::from_error_msg(code, message))
}
#[inline(always)]
pub fn from_error_source(
code: impl Into<u32>,
source: impl Error + Send + Sync + 'static,
set_source_detail: bool,
message: Option<String>,
) -> Self {
Self::Error(ErrorResponse::from_error_source(
code,
source,
set_source_detail,
message,
))
}
#[inline(always)]
pub fn with_meta(mut self, meta: Meta) -> Self {
self.set_meta(meta);
self
}
#[inline(always)]
pub fn set_meta(&mut self, meta: Meta) -> &mut Self {
match self {
ApiResponse::Success(success_response) => {
success_response.set_meta(meta);
}
ApiResponse::Error(error_response) => {
error_response.set_meta(meta);
}
}
self
}
pub const fn is_success(&self) -> bool {
matches!(self, Self::Success(_))
}
pub const fn is_error(&self) -> bool {
matches!(self, Self::Error(_))
}
pub const fn get_meta(&self) -> Option<&Meta> {
match self {
ApiResponse::Success(success_response) => success_response.meta.as_ref(),
ApiResponse::Error(error_response) => error_response.meta.as_ref(),
}
}
pub fn expect(self, expect_msg: &str) -> SuccessResponse<Data, Meta> {
match self {
ApiResponse::Success(success_response) => success_response,
ApiResponse::Error(_) => {
panic!("{expect_msg}")
}
}
}
pub fn unwrap(self) -> SuccessResponse<Data, Meta> {
match self {
ApiResponse::Success(success_response) => success_response,
ApiResponse::Error(_) => {
panic!("called `ApiResponse::unwrap()` on an `ApiResponse::Error` value")
}
}
}
pub fn unwrap_err(self) -> ErrorResponse<Meta> {
match self {
ApiResponse::Success(_) => {
panic!("called `ApiResponse::unwrap_err()` on an `ApiResponse::Success` value")
}
ApiResponse::Error(error_response) => error_response,
}
}
pub fn into_result(self) -> ApiResult<Data, Meta> {
self.into()
}
pub fn into_result_data(self) -> Result<Data, ErrorResponse<Meta>> {
match self {
ApiResponse::Success(success_response) => Ok(success_response.data),
ApiResponse::Error(error_response) => Err(error_response),
}
}
pub fn into_result_without_meta(self) -> Result<Data, ApiError> {
match self {
ApiResponse::Success(success_response) => Ok(success_response.data),
ApiResponse::Error(error_response) => Err(error_response.error),
}
}
}