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