cal-core 0.2.158

Callable core lib
Documentation
// File: cal-core/src/queue.rs

use crate::{ContactRef, RecordReference};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, VecDeque};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct QueueGroup {
    pub name: String,
    #[serde(rename = "type")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub queue_type: Option<String>,
    pub device_id: String,
    pub account_id: String,
    pub entries: VecDeque<Entry>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Entry {
    pub call_sid: String,
    pub from: String,
    pub priority: i32,
    pub timestamp: i64,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub contact: Option<ContactRef>,
}

impl QueueGroup {
    pub fn new(name: String, queue_type: Option<String>, device_id: String, account_id: String) -> Self {
        Self {
            name,
            queue_type,
            device_id,
            account_id,
            entries: VecDeque::new(),
        }
    }

    pub fn get_type(&self) -> String {
        self.queue_type.clone().unwrap_or_else(|| "callable-queue".to_string())
    }

    pub fn add(&mut self, call_sid: String, from: String, priority: i32, contact: Option<ContactRef>) -> Entry {
        let entry = Entry {
            call_sid: call_sid.clone(),
            from,
            priority,
            timestamp: chrono::Utc::now().timestamp_millis(),
            contact,
        };
        self.entries.push_back(entry.clone());
        entry
    }

    pub fn remove(&mut self, call_sid: &str) {
        self.entries.retain(|entry| entry.call_sid != call_sid);
    }

    pub fn pop(&mut self) -> Option<Entry> {
        self.entries.pop_front()
    }

    pub fn pop_by_priority(&mut self) -> Option<Entry> {
        if self.entries.is_empty() {
            return None;
        }

        // Find the index of the entry with the minimum prioritized timestamp
        let min_index = self.entries
            .iter()
            .enumerate()
            .min_by_key(|(_, entry)| entry.get_prioritized_timestamp())
            .map(|(index, _)| index)?;

        // Remove and return the entry at that index
        self.entries.remove(min_index)
    }
}

impl Entry {
    pub fn get_prioritized_timestamp(&self) -> i64 {
        // Lower priority number = higher priority (1 is highest)
        // Multiply by -1 to reverse the order so lower numbers come first
        self.timestamp * (self.priority as i64) * -1
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct QueueStat {
    #[serde(rename = "_id")]
    pub id: String,
    pub timestamp: DateTime<Utc>,
    pub meta: MetaData,
    pub entry: Entry,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user: Option<RecordReference>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub contact: Option<ContactRef>,
    pub queue_name: String,
    pub queue_time: Option<i64>,
    pub queue_count: Option<i64>,
    pub status: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data: Option<BTreeMap<String, String>>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MetaData {
    pub account: RecordReference,
    pub device: RecordReference,
}

impl QueueStat {
    pub fn new(
        id: String,
        timestamp: DateTime<Utc>,
        meta: MetaData,
        entry: Entry,
        user: Option<RecordReference>,
        contact: Option<ContactRef>,
        queue_name: String,
        queue_time: Option<i64>,
        queue_count: Option<i64>,
        status: String,
        data: Option<BTreeMap<String, String>>,
    ) -> Self {
        Self {
            id,
            timestamp,
            meta,
            entry,
            user,
            contact,
            queue_name,
            queue_time,
            queue_count,
            status,
            data,
        }
    }
}

impl MetaData {
    pub fn new(account: RecordReference, device: RecordReference) -> Self {
        Self { account, device }
    }
}

// If you need Display implementations
impl std::fmt::Display for QueueStat {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "QueueStat(id={}, timestamp={}, meta={:?}, entry={:?}, user={:?}, contact={:?}, \
             queueName={}, queueTime={:?}, queueCount={:?}, status={}, data={:?})",
            self.id,
            self.timestamp,
            self.meta,
            self.entry,
            self.user,
            self.contact,
            self.queue_name,
            self.queue_time,
            self.queue_count,
            self.status,
            self.data
        )
    }
}

impl std::fmt::Display for MetaData {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "QueueStat.MetaData(account={:?}, device={:?})",
            self.account, self.device
        )
    }
}