1#![deny(non_ascii_idents)]
19#![allow(clippy::disallowed_names)]
21#![allow(clippy::blanket_clippy_restriction_lints)]
23#![warn(clippy::missing_panics_doc)]
25#![warn(clippy::shadow_reuse, clippy::shadow_same, clippy::shadow_unrelated)]
27#![warn(clippy::missing_const_for_fn)]
29#![warn(
31 clippy::cast_lossless,
32 clippy::cast_possible_truncation,
33 clippy::cast_possible_wrap,
34 clippy::ptr_as_ptr
35)]
36#![warn(clippy::many_single_char_names)]
39#![warn(clippy::default_numeric_fallback)]
41#![warn(clippy::checked_conversions)]
43#![warn(clippy::match_bool)]
45#![warn(clippy::needless_bitwise_bool)]
48#![deny(clippy::cast_sign_loss)]
50#![warn(clippy::modulo_arithmetic)]
52#![warn(clippy::cast_precision_loss)]
55#![warn(clippy::float_arithmetic, clippy::float_cmp, clippy::float_cmp_const)]
57#![warn(clippy::imprecise_flops, clippy::suboptimal_flops)]
59#![warn(clippy::large_stack_arrays)]
61#![warn(clippy::exhaustive_structs)]
63#![warn(clippy::exhaustive_enums)]
65#![warn(clippy::struct_excessive_bools)]
67#![warn(clippy::fn_params_excessive_bools)]
70#![warn(clippy::enum_glob_use)]
72#![warn(clippy::else_if_without_else)]
74#![warn(clippy::string_add_assign, clippy::string_add)]
76#![warn(clippy::string_lit_as_bytes)]
79#![warn(clippy::string_slice)]
81#![warn(clippy::large_types_passed_by_value)]
83#![warn(clippy::trivially_copy_pass_by_ref)]
85#![warn(clippy::inefficient_to_string)]
88#![warn(clippy::default_trait_access)]
90#![warn(clippy::copy_iterator)]
92#![warn(clippy::cloned_instead_of_copied)]
94#![warn(clippy::unwrap_used)]
96#![warn(clippy::wildcard_imports)]
98#![warn(clippy::self_named_module_files)]
100#![warn(clippy::cargo_common_metadata)]
102#![warn(clippy::negative_feature_names, clippy::redundant_feature_names)]
104#![warn(clippy::wildcard_dependencies)]
106#![warn(clippy::dbg_macro)]
108#![warn(clippy::await_holding_lock)]
110#![warn(clippy::await_holding_refcell_ref)]
112#![warn(clippy::unused_async)]
114#![warn(clippy::debug_assert_with_mut_call)]
116#![cfg_attr(feature = "try", feature(try_trait_v2))]
117
118#[cfg(feature = "try")]
119mod try_trait;
120
121#[cfg(feature = "salvo")]
122mod salvo_trait;
123
124mod error;
125pub mod error_code;
126#[cfg(feature = "lite")]
127pub(crate) mod lite;
128mod meta;
129mod result;
130mod success;
131mod utils;
132
133use std::{error::Error, fmt::Debug};
134
135pub use prelude::*;
136pub mod prelude {
137 pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
138
139 pub use crate::{
140 ApiResponse, api_err,
141 error::{ApiError, ErrorResponse},
142 error_code,
143 error_code::ety_grpc,
144 meta::{Cost, DefaultMeta, Pagination, RateLimit, UserMeta},
145 result::ApiResult,
146 success::{ApiSuccessResponse, SuccessResponse},
147 utils::{ErrWrapper, IntoError, MaybeString},
148 };
149}
150
151#[cfg_attr(not(feature = "lite"), derive(Serialize, Deserialize))]
153#[cfg_attr(not(feature = "lite"), serde(tag = "status", rename_all = "lowercase"))]
154#[derive(Debug)]
155#[allow(clippy::exhaustive_enums)]
156pub enum ApiResponse<Data, Meta> {
157 Success(SuccessResponse<Data, Meta>),
158 Error(ErrorResponse<Meta>),
159}
160
161impl<Data, Meta> From<SuccessResponse<Data, Meta>> for ApiResponse<Data, Meta> {
162 fn from(value: SuccessResponse<Data, Meta>) -> Self {
163 Self::Success(value)
164 }
165}
166
167impl<Data, Meta> From<ErrorResponse<Meta>> for ApiResponse<Data, Meta> {
168 fn from(value: ErrorResponse<Meta>) -> Self {
169 Self::Error(value)
170 }
171}
172
173impl<Data, Meta> From<ApiError> for ApiResponse<Data, Meta> {
174 fn from(error: ApiError) -> Self {
175 ApiResponse::Error(ErrorResponse::from_error(error))
176 }
177}
178
179impl<Data, Meta> ApiResponse<Data, Meta> {
180 #[inline(always)]
181 pub const fn new_success(data: Data, meta: Meta) -> Self {
182 Self::Success(SuccessResponse::new(data, meta))
183 }
184 #[inline(always)]
185 pub const fn from_success(data: Data) -> Self {
186 Self::Success(SuccessResponse::from_data(data))
187 }
188 #[inline(always)]
189 pub const fn from_success_data(data: Data) -> Self {
190 Self::Success(SuccessResponse::from_data(data))
191 }
192 #[inline(always)]
193 pub const fn new_error(error: ApiError, meta: Meta) -> Self {
194 Self::Error(ErrorResponse::new(error, meta))
195 }
196 #[inline(always)]
197 pub const fn from_error(error: ApiError) -> Self {
198 Self::Error(ErrorResponse::from_error(error))
199 }
200 #[inline(always)]
201 pub fn from_error_msg(code: impl Into<u32>, message: impl Into<String>) -> Self {
202 Self::Error(ErrorResponse::from_error_msg(code, message))
203 }
204 #[inline(always)]
205 pub fn from_error_source(
206 code: impl Into<u32>,
207 source: impl Error + Send + Sync + 'static,
208 set_source_detail: bool,
209 message: Option<String>,
210 ) -> Self {
211 Self::Error(ErrorResponse::from_error_source(
212 code,
213 source,
214 set_source_detail,
215 message,
216 ))
217 }
218 #[inline(always)]
219 pub fn with_meta(mut self, meta: Meta) -> Self {
220 self.set_meta(meta);
221 self
222 }
223 #[inline(always)]
224 pub fn set_meta(&mut self, meta: Meta) -> &mut Self {
225 match self {
226 ApiResponse::Success(success_response) => {
227 success_response.set_meta(meta);
228 }
229 ApiResponse::Error(error_response) => {
230 error_response.set_meta(meta);
231 }
232 }
233 self
234 }
235 pub const fn is_success(&self) -> bool {
236 matches!(self, Self::Success(_))
237 }
238 pub const fn is_error(&self) -> bool {
239 matches!(self, Self::Error(_))
240 }
241 pub const fn get_meta(&self) -> Option<&Meta> {
242 match self {
243 ApiResponse::Success(success_response) => success_response.meta.as_ref(),
244 ApiResponse::Error(error_response) => error_response.meta.as_ref(),
245 }
246 }
247 pub fn expect(self, expect_msg: &str) -> SuccessResponse<Data, Meta> {
251 match self {
252 ApiResponse::Success(success_response) => success_response,
253 ApiResponse::Error(_) => {
254 panic!("{expect_msg}")
255 }
256 }
257 }
258 pub fn unwrap(self) -> SuccessResponse<Data, Meta> {
261 match self {
262 ApiResponse::Success(success_response) => success_response,
263 ApiResponse::Error(_) => {
264 panic!("called `ApiResponse::unwrap()` on an `ApiResponse::Error` value")
265 }
266 }
267 }
268 pub fn unwrap_err(self) -> ErrorResponse<Meta> {
271 match self {
272 ApiResponse::Success(_) => {
273 panic!("called `ApiResponse::unwrap_err()` on an `ApiResponse::Success` value")
274 }
275 ApiResponse::Error(error_response) => error_response,
276 }
277 }
278 pub fn into_result(self) -> ApiResult<Data, Meta> {
279 self.into()
280 }
281 pub fn into_result_data(self) -> Result<Data, ErrorResponse<Meta>> {
282 match self {
283 ApiResponse::Success(success_response) => Ok(success_response.data),
284 ApiResponse::Error(error_response) => Err(error_response),
285 }
286 }
287 pub fn into_result_without_meta(self) -> Result<Data, ApiError> {
288 match self {
289 ApiResponse::Success(success_response) => Ok(success_response.data),
290 ApiResponse::Error(error_response) => Err(error_response.error),
291 }
292 }
293}