cal-core 0.2.158

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

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentStatus {
    pub user_id: String,
    pub account_id: String,
    pub agent_name: String,
    pub agent_status: String,
    pub registration: Option<UserRegistration>,
    pub user_call_status: Option<UserCallStatus>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserRegistration {
    pub registered: bool,
    pub registration_time: Option<i64>,
    pub sip_uri: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserCallStatus {
    pub status: String,
    pub state: Option<SipSessionState>,
    pub start_time: Option<i64>,
    pub answer_time: Option<i64>,
    pub remote_party: Option<String>,
    pub call_sid: Option<String>,
    pub direction: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SipSessionState {
    pub state: String,
    pub end_state: Option<EndState>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EndState {
    pub status: String,
    pub cause: Option<String>,
}

impl AgentStatus {

    pub fn is_registered(&self) -> bool {
        self.registration
            .as_ref()
            .map(|r| r.registered)
            .unwrap_or(false)
    }

    pub fn get_agent_name(&self) -> &str {
        self.agent_name.as_str()
    }

    pub fn get_user_presence(&self) -> &str {
        &self.agent_status.as_str()
    }

    pub fn is_available(&self) -> bool {
        self.get_user_presence() == "available"
    }

    pub fn get_call_presence(&self) -> String {
        self.user_call_status
            .as_ref()
            .and_then(|status| {
                if status.status != "ended" {
                    Some(status.status.clone())
                } else {
                    None
                }
            })
            .unwrap_or_else(|| self.get_user_presence().to_string())
    }

    pub fn get_user_presence_title(&self) -> String {
        let presence = self.get_user_presence();
        if let Some(first_char) = presence.chars().next() {
            first_char.to_uppercase().collect::<String>() + &presence[1..]
        } else {
            presence.to_string()
        }
    }

    pub fn is_active(&self) -> bool {
        self.user_call_status
            .as_ref()
            .map(|status| status.is_active())
            .unwrap_or(false)
    }

    pub fn is_not_active(&self) -> bool {
        !self.is_active()
    }

    pub fn get_start_time(&self) -> i64 {
        self.user_call_status
            .as_ref()
            .and_then(|status| status.start_time)
            .unwrap_or_else(|| chrono::Utc::now().timestamp_millis())
    }

    pub fn get_answer_time(&self) -> i64 {
        self.user_call_status
            .as_ref()
            .and_then(|status| status.answer_time)
            .unwrap_or_else(|| chrono::Utc::now().timestamp_millis())
    }

    pub fn get_remote_party(&self) -> Option<&str> {
        self.user_call_status
            .as_ref()
            .and_then(|status| status.remote_party.as_deref())
    }

    pub fn get_failed_reason(&self) -> Option<String> {
        self.user_call_status
            .as_ref()
            .and_then(|status| status.state.as_ref())
            .and_then(|state| state.end_state.as_ref())
            .and_then(|end_state| end_state.cause.clone())
    }

    pub fn get_failed(&self) -> bool {
        self.user_call_status
            .as_ref()
            .and_then(|status| status.state.as_ref())
            .and_then(|state| state.end_state.as_ref())
            .map(|end_state| end_state.status == "failed")
            .unwrap_or(false)
    }
}

impl UserRegistration {
    pub fn is_registered(&self) -> bool {
        self.registered
    }
}

impl UserCallStatus {
    pub fn is_active(&self) -> bool {
        matches!(self.status.as_str(), "active" | "ringing" | "in-progress" | "connected")
    }
}

// Keep the simple update structures
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentStatusUpdate {
    pub agent_id: String,
    pub new_status: AgentStatusType,
    pub reason: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AgentStatusType {
    Available,
    Busy,
    Away,
    Offline,
    Break,
    Lunch,
    Training,
    Meeting,
}