cal_core/
queue.rs

1// File: cal-core/src/queue.rs
2
3use serde::{Deserialize, Serialize};
4use std::collections::VecDeque;
5use crate::conversation::Contact;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct QueueGroup {
10    pub name: String,
11    #[serde(rename = "type")]
12    pub queue_type: Option<String>,
13    pub device_id: String,
14    pub account_id: String,
15    pub entries: VecDeque<Entry>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct Entry {
21    pub call_sid: String,
22    pub from: String,
23    pub priority: i32,
24    pub timestamp: i64,
25    pub contact: Option<Contact>,
26}
27
28impl QueueGroup {
29    pub fn new(name: String, queue_type: Option<String>, device_id: String, account_id: String) -> Self {
30        Self {
31            name,
32            queue_type,
33            device_id,
34            account_id,
35            entries: VecDeque::new(),
36        }
37    }
38
39    pub fn get_type(&self) -> String {
40        self.queue_type.clone().unwrap_or_else(|| "callable-queue".to_string())
41    }
42
43    pub fn add(&mut self, call_sid: String, from: String, priority: i32, contact: Option<Contact>) -> Entry {
44        let entry = Entry {
45            call_sid: call_sid.clone(),
46            from,
47            priority,
48            timestamp: chrono::Utc::now().timestamp_millis(),
49            contact,
50        };
51        self.entries.push_back(entry.clone());
52        entry
53    }
54
55    pub fn remove(&mut self, call_sid: &str) {
56        self.entries.retain(|entry| entry.call_sid != call_sid);
57    }
58
59    pub fn pop(&mut self) -> Option<Entry> {
60        self.entries.pop_front()
61    }
62
63    pub fn pop_by_priority(&mut self) -> Option<Entry> {
64        if self.entries.is_empty() {
65            return None;
66        }
67
68        // Find the index of the entry with the minimum prioritized timestamp
69        let min_index = self.entries
70            .iter()
71            .enumerate()
72            .min_by_key(|(_, entry)| entry.get_prioritized_timestamp())
73            .map(|(index, _)| index)?;
74
75        // Remove and return the entry at that index
76        self.entries.remove(min_index)
77    }
78}
79
80impl Entry {
81    pub fn get_prioritized_timestamp(&self) -> i64 {
82        // Lower priority number = higher priority (1 is highest)
83        // Multiply by -1 to reverse the order so lower numbers come first
84        self.timestamp * (self.priority as i64) * -1
85    }
86}