use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use winterbaume_core::{StateChangeNotifier, StateViewError, StatefulService};
use crate::handlers::SupportService;
use crate::state::SupportState;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct SupportStateView {
#[serde(default)]
pub cases: HashMap<String, SupportCaseView>,
#[serde(default)]
pub refresh_call_counts: HashMap<String, usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupportCaseView {
pub case_id: String,
pub display_id: String,
pub subject: String,
pub status: String,
pub service_code: String,
pub category_code: String,
pub severity_code: String,
pub communication_body: String,
pub submitted_by: String,
pub time_created: String,
#[serde(default)]
pub cc_email_addresses: Vec<String>,
pub language: String,
}
impl From<&SupportState> for SupportStateView {
fn from(state: &SupportState) -> Self {
SupportStateView {
cases: state
.cases
.iter()
.map(|(k, v)| {
(
k.clone(),
SupportCaseView {
case_id: v.case_id.clone(),
display_id: v.display_id.clone(),
subject: v.subject.clone(),
status: v.status.clone(),
service_code: v.service_code.clone(),
category_code: v.category_code.clone(),
severity_code: v.severity_code.clone(),
communication_body: v.communication_body.clone(),
submitted_by: v.submitted_by.clone(),
time_created: v.time_created.clone(),
cc_email_addresses: v.cc_email_addresses.clone(),
language: v.language.clone(),
},
)
})
.collect(),
refresh_call_counts: state.refresh_call_counts.clone(),
}
}
}
fn support_state_from_view(view: SupportStateView) -> SupportState {
use crate::types::SupportCase;
let mut state = SupportState::default();
state.cases = view
.cases
.into_iter()
.map(|(k, v)| {
(
k,
SupportCase {
case_id: v.case_id,
display_id: v.display_id,
subject: v.subject,
status: v.status,
service_code: v.service_code,
category_code: v.category_code,
severity_code: v.severity_code,
communication_body: v.communication_body,
submitted_by: v.submitted_by,
time_created: v.time_created,
cc_email_addresses: v.cc_email_addresses,
language: v.language,
},
)
})
.collect();
state.refresh_call_counts = view.refresh_call_counts;
state
}
impl StatefulService for SupportService {
type StateView = SupportStateView;
async fn snapshot(&self, account_id: &str, region: &str) -> Self::StateView {
let state = self.state.get(account_id, region);
let guard = state.read().await;
SupportStateView::from(&*guard)
}
async fn restore(
&self,
account_id: &str,
region: &str,
view: Self::StateView,
) -> Result<(), StateViewError> {
let state = self.state.get(account_id, region);
{
let mut guard = state.write().await;
*guard = support_state_from_view(view);
}
self.notify_state_changed(account_id, region).await;
Ok(())
}
async fn merge(
&self,
account_id: &str,
region: &str,
view: Self::StateView,
) -> Result<(), StateViewError> {
let state = self.state.get(account_id, region);
{
let mut guard = state.write().await;
for (k, v) in view.cases {
use crate::types::SupportCase;
guard.cases.insert(
k,
SupportCase {
case_id: v.case_id,
display_id: v.display_id,
subject: v.subject,
status: v.status,
service_code: v.service_code,
category_code: v.category_code,
severity_code: v.severity_code,
communication_body: v.communication_body,
submitted_by: v.submitted_by,
time_created: v.time_created,
cc_email_addresses: v.cc_email_addresses,
language: v.language,
},
);
}
for (k, v) in view.refresh_call_counts {
guard.refresh_call_counts.insert(k, v);
}
}
self.notify_state_changed(account_id, region).await;
Ok(())
}
fn notifier(&self) -> &StateChangeNotifier<Self::StateView> {
&self.notifier
}
}