1use crate::{ContactRef, RecordReference};
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use std::collections::{BTreeMap, VecDeque};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct QueueGroup {
11 pub name: String,
12 #[serde(rename = "type")]
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub queue_type: Option<String>,
15 pub device_id: String,
16 pub account_id: String,
17 pub entries: VecDeque<Entry>,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21#[serde(rename_all = "camelCase")]
22pub struct Entry {
23 pub call_sid: String,
24 pub from: String,
25 pub priority: i32,
26 pub timestamp: i64,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub contact: Option<ContactRef>,
29}
30
31impl QueueGroup {
32 pub fn new(name: String, queue_type: Option<String>, device_id: String, account_id: String) -> Self {
33 Self {
34 name,
35 queue_type,
36 device_id,
37 account_id,
38 entries: VecDeque::new(),
39 }
40 }
41
42 pub fn get_type(&self) -> String {
43 self.queue_type.clone().unwrap_or_else(|| "callable-queue".to_string())
44 }
45
46 pub fn add(&mut self, call_sid: String, from: String, priority: i32, contact: Option<ContactRef>) -> Entry {
47 let entry = Entry {
48 call_sid: call_sid.clone(),
49 from,
50 priority,
51 timestamp: chrono::Utc::now().timestamp_millis(),
52 contact,
53 };
54 self.entries.push_back(entry.clone());
55 entry
56 }
57
58 pub fn remove(&mut self, call_sid: &str) {
59 self.entries.retain(|entry| entry.call_sid != call_sid);
60 }
61
62 pub fn pop(&mut self) -> Option<Entry> {
63 self.entries.pop_front()
64 }
65
66 pub fn pop_by_priority(&mut self) -> Option<Entry> {
67 if self.entries.is_empty() {
68 return None;
69 }
70
71 let min_index = self.entries
73 .iter()
74 .enumerate()
75 .min_by_key(|(_, entry)| entry.get_prioritized_timestamp())
76 .map(|(index, _)| index)?;
77
78 self.entries.remove(min_index)
80 }
81}
82
83impl Entry {
84 pub fn get_prioritized_timestamp(&self) -> i64 {
85 self.timestamp * (self.priority as i64) * -1
88 }
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase")]
93pub struct QueueStat {
94 #[serde(rename = "_id")]
95 pub id: String,
96 pub timestamp: DateTime<Utc>,
97 pub meta: MetaData,
98 pub entry: Entry,
99 #[serde(skip_serializing_if = "Option::is_none")]
100 pub user: Option<RecordReference>,
101 #[serde(skip_serializing_if = "Option::is_none")]
102 pub contact: Option<ContactRef>,
103 pub queue_name: String,
104 pub queue_time: Option<i64>,
105 pub queue_count: Option<i64>,
106 pub status: String,
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub data: Option<BTreeMap<String, String>>,
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
112#[serde(rename_all = "camelCase")]
113pub struct MetaData {
114 pub account: RecordReference,
115 pub device: RecordReference,
116}
117
118impl QueueStat {
119 pub fn new(
120 id: String,
121 timestamp: DateTime<Utc>,
122 meta: MetaData,
123 entry: Entry,
124 user: Option<RecordReference>,
125 contact: Option<ContactRef>,
126 queue_name: String,
127 queue_time: Option<i64>,
128 queue_count: Option<i64>,
129 status: String,
130 data: Option<BTreeMap<String, String>>,
131 ) -> Self {
132 Self {
133 id,
134 timestamp,
135 meta,
136 entry,
137 user,
138 contact,
139 queue_name,
140 queue_time,
141 queue_count,
142 status,
143 data,
144 }
145 }
146}
147
148impl MetaData {
149 pub fn new(account: RecordReference, device: RecordReference) -> Self {
150 Self { account, device }
151 }
152}
153
154impl std::fmt::Display for QueueStat {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 write!(
158 f,
159 "QueueStat(id={}, timestamp={}, meta={:?}, entry={:?}, user={:?}, contact={:?}, \
160 queueName={}, queueTime={:?}, queueCount={:?}, status={}, data={:?})",
161 self.id,
162 self.timestamp,
163 self.meta,
164 self.entry,
165 self.user,
166 self.contact,
167 self.queue_name,
168 self.queue_time,
169 self.queue_count,
170 self.status,
171 self.data
172 )
173 }
174}
175
176impl std::fmt::Display for MetaData {
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 write!(
179 f,
180 "QueueStat.MetaData(account={:?}, device={:?})",
181 self.account, self.device
182 )
183 }
184}