openzeppelin_relayer/models/
api_response.rs1use serde::{Deserialize, Serialize};
2use utoipa::ToSchema;
3
4#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, ToSchema)]
5pub struct PaginationMeta {
6 pub current_page: u32,
7 pub per_page: u32,
8 pub total_items: u64,
9}
10
11#[derive(Serialize, Deserialize, ToSchema)]
12pub struct ApiResponse<T> {
13 pub success: bool,
14 pub data: Option<T>,
15 #[schema(nullable = false)]
16 pub error: Option<String>,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 #[schema(nullable = false)]
19 pub pagination: Option<PaginationMeta>,
20}
21
22#[allow(dead_code)]
23impl<T> ApiResponse<T> {
24 pub fn new(data: Option<T>, error: Option<String>, pagination: Option<PaginationMeta>) -> Self {
25 Self {
26 success: error.is_none(),
27 data,
28 error,
29 pagination,
30 }
31 }
32
33 pub fn success(data: T) -> Self {
34 Self {
35 success: true,
36 data: Some(data),
37 error: None,
38 pagination: None,
39 }
40 }
41
42 pub fn error(message: impl Into<String>) -> Self {
43 Self {
44 success: false,
45 data: None,
46 error: Some(message.into()),
47 pagination: None,
48 }
49 }
50
51 pub fn no_data() -> Self {
52 Self {
53 success: true,
54 data: None,
55 error: None,
56 pagination: None,
57 }
58 }
59
60 pub fn paginated(data: T, meta: PaginationMeta) -> Self {
61 Self {
62 success: true,
63 data: Some(data),
64 error: None,
65 pagination: Some(meta),
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_new_with_data() {
76 let data = "test data";
77 let response = ApiResponse::new(Some(data), None, None);
78
79 assert!(response.success);
80 assert_eq!(response.data, Some(data));
81 assert_eq!(response.error, None);
82 assert_eq!(response.pagination, None);
83 }
84
85 #[test]
86 fn test_new_with_error() {
87 let error = "test error";
88 let response: ApiResponse<()> = ApiResponse::new(None, Some(error.to_string()), None);
89
90 assert!(!response.success);
91 assert_eq!(response.data, None);
92 assert_eq!(response.error, Some(error.to_string()));
93 assert_eq!(response.pagination, None);
94 }
95
96 #[test]
97 fn test_success() {
98 let data = "test data";
99 let response = ApiResponse::success(data);
100
101 assert!(response.success);
102 assert_eq!(response.data, Some(data));
103 assert_eq!(response.error, None);
104 assert_eq!(response.pagination, None);
105 }
106
107 #[test]
108 fn test_error() {
109 let error = "test error";
110 let response: ApiResponse<()> = ApiResponse::error(error);
111
112 assert!(!response.success);
113 assert_eq!(response.data, None);
114 assert_eq!(response.error, Some(error.to_string()));
115 assert_eq!(response.pagination, None);
116 }
117
118 #[test]
119 fn test_no_data() {
120 let response: ApiResponse<String> = ApiResponse::no_data();
121
122 assert!(response.success);
123 assert_eq!(response.data, None);
124 assert_eq!(response.error, None);
125 assert_eq!(response.pagination, None);
126 }
127
128 #[test]
129 fn test_paginated() {
130 let data = "test data";
131 let pagination = PaginationMeta {
132 current_page: 1,
133 per_page: 10,
134 total_items: 100,
135 };
136
137 let response = ApiResponse::paginated(data, pagination.clone());
138
139 assert!(response.success);
140 assert_eq!(response.data, Some(data));
141 assert_eq!(response.error, None);
142 assert_eq!(response.pagination, Some(pagination));
143 }
144}