1use std::collections::HashMap;
4
5use serde::{Deserialize, Serialize};
6use winterbaume_core::{StateChangeNotifier, StateViewError, StatefulService};
7
8use crate::handlers::SupportService;
9use crate::state::SupportState;
10
11#[derive(Debug, Clone, Serialize, Deserialize, Default)]
13pub struct SupportStateView {
14 #[serde(default)]
16 pub cases: HashMap<String, SupportCaseView>,
17 #[serde(default)]
19 pub refresh_call_counts: HashMap<String, usize>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct SupportCaseView {
25 pub case_id: String,
26 pub display_id: String,
27 pub subject: String,
28 pub status: String,
29 pub service_code: String,
30 pub category_code: String,
31 pub severity_code: String,
32 pub communication_body: String,
33 pub submitted_by: String,
34 pub time_created: String,
35 #[serde(default)]
36 pub cc_email_addresses: Vec<String>,
37 pub language: String,
38}
39
40impl From<&SupportState> for SupportStateView {
43 fn from(state: &SupportState) -> Self {
44 SupportStateView {
45 cases: state
46 .cases
47 .iter()
48 .map(|(k, v)| {
49 (
50 k.clone(),
51 SupportCaseView {
52 case_id: v.case_id.clone(),
53 display_id: v.display_id.clone(),
54 subject: v.subject.clone(),
55 status: v.status.clone(),
56 service_code: v.service_code.clone(),
57 category_code: v.category_code.clone(),
58 severity_code: v.severity_code.clone(),
59 communication_body: v.communication_body.clone(),
60 submitted_by: v.submitted_by.clone(),
61 time_created: v.time_created.clone(),
62 cc_email_addresses: v.cc_email_addresses.clone(),
63 language: v.language.clone(),
64 },
65 )
66 })
67 .collect(),
68 refresh_call_counts: state.refresh_call_counts.clone(),
69 }
70 }
71}
72
73fn support_state_from_view(view: SupportStateView) -> SupportState {
76 use crate::types::SupportCase;
77 let mut state = SupportState::default();
78 state.cases = view
79 .cases
80 .into_iter()
81 .map(|(k, v)| {
82 (
83 k,
84 SupportCase {
85 case_id: v.case_id,
86 display_id: v.display_id,
87 subject: v.subject,
88 status: v.status,
89 service_code: v.service_code,
90 category_code: v.category_code,
91 severity_code: v.severity_code,
92 communication_body: v.communication_body,
93 submitted_by: v.submitted_by,
94 time_created: v.time_created,
95 cc_email_addresses: v.cc_email_addresses,
96 language: v.language,
97 },
98 )
99 })
100 .collect();
101 state.refresh_call_counts = view.refresh_call_counts;
102 state
103}
104
105impl StatefulService for SupportService {
108 type StateView = SupportStateView;
109
110 async fn snapshot(&self, account_id: &str, region: &str) -> Self::StateView {
111 let state = self.state.get(account_id, region);
112 let guard = state.read().await;
113 SupportStateView::from(&*guard)
114 }
115
116 async fn restore(
117 &self,
118 account_id: &str,
119 region: &str,
120 view: Self::StateView,
121 ) -> Result<(), StateViewError> {
122 let state = self.state.get(account_id, region);
123 {
124 let mut guard = state.write().await;
125 *guard = support_state_from_view(view);
126 }
127 self.notify_state_changed(account_id, region).await;
128 Ok(())
129 }
130
131 async fn merge(
132 &self,
133 account_id: &str,
134 region: &str,
135 view: Self::StateView,
136 ) -> Result<(), StateViewError> {
137 let state = self.state.get(account_id, region);
138 {
139 let mut guard = state.write().await;
140 for (k, v) in view.cases {
141 use crate::types::SupportCase;
142 guard.cases.insert(
143 k,
144 SupportCase {
145 case_id: v.case_id,
146 display_id: v.display_id,
147 subject: v.subject,
148 status: v.status,
149 service_code: v.service_code,
150 category_code: v.category_code,
151 severity_code: v.severity_code,
152 communication_body: v.communication_body,
153 submitted_by: v.submitted_by,
154 time_created: v.time_created,
155 cc_email_addresses: v.cc_email_addresses,
156 language: v.language,
157 },
158 );
159 }
160 for (k, v) in view.refresh_call_counts {
161 guard.refresh_call_counts.insert(k, v);
162 }
163 }
164 self.notify_state_changed(account_id, region).await;
165 Ok(())
166 }
167
168 fn notifier(&self) -> &StateChangeNotifier<Self::StateView> {
169 &self.notifier
170 }
171}