1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ApiResponse<T> {
8 pub success: bool,
10
11 #[serde(skip_serializing_if = "Option::is_none")]
13 pub result: Option<T>,
14
15 #[serde(default)]
17 pub errors: Vec<ApiErrorDetail>,
18
19 #[serde(default)]
21 pub messages: Vec<String>,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub result_info: Option<ResultInfo>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ApiErrorDetail {
31 pub code: i32,
33
34 pub message: String,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ResultInfo {
41 pub page: u32,
43
44 pub per_page: u32,
46
47 pub total_pages: u32,
49
50 pub count: u32,
52
53 pub total_count: u32,
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
59pub enum ChangeAction {
60 Create,
62
63 Update,
65
66 Delete,
68
69 NoChange,
71}
72
73impl ChangeAction {
74 pub fn is_mutating(&self) -> bool {
76 matches!(
77 self,
78 ChangeAction::Create | ChangeAction::Update | ChangeAction::Delete
79 )
80 }
81}
82
83#[derive(Debug, Clone)]
85pub struct Change<T> {
86 pub action: ChangeAction,
88
89 pub current: Option<T>,
91
92 pub desired: Option<T>,
94
95 pub description: String,
97}
98
99impl<T> Change<T> {
100 pub fn create(desired: T, description: String) -> Self {
102 Self {
103 action: ChangeAction::Create,
104 current: None,
105 desired: Some(desired),
106 description,
107 }
108 }
109
110 pub fn update(current: T, desired: T, description: String) -> Self {
112 Self {
113 action: ChangeAction::Update,
114 current: Some(current),
115 desired: Some(desired),
116 description,
117 }
118 }
119
120 pub fn no_change(current: T, description: String) -> Self {
122 Self {
123 action: ChangeAction::NoChange,
124 current: Some(current),
125 desired: None,
126 description,
127 }
128 }
129}