asterisk-rs-ami 0.8.0

Async Rust client for the Asterisk Manager Interface (AMI)
Documentation
//! AMI-specific error types.

use asterisk_rs_core::error::{AuthError, ConnectionError, ProtocolError, TimeoutError};

/// Cloneable terminal connection cause retained after the background actor exits.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AmiTerminalError {
    pub kind: AmiTerminalErrorKind,
    pub details: String,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum AmiTerminalErrorKind {
    Authentication,
    Connection,
    Timeout,
    Protocol,
    Io,
    Other,
}

impl AmiTerminalError {
    pub(crate) fn from_error(error: &AmiError) -> Self {
        let kind = match error {
            AmiError::Auth(_) => AmiTerminalErrorKind::Authentication,
            AmiError::Connection(_) => AmiTerminalErrorKind::Connection,
            AmiError::Timeout(_) => AmiTerminalErrorKind::Timeout,
            AmiError::Protocol(_) => AmiTerminalErrorKind::Protocol,
            AmiError::Io(_) => AmiTerminalErrorKind::Io,
            _ => AmiTerminalErrorKind::Other,
        };
        Self {
            kind,
            details: error.to_string(),
        }
    }
}

/// errors specific to AMI operations
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum AmiError {
    #[error("connection error: {0}")]
    Connection(#[from] ConnectionError),

    #[error("authentication error: {0}")]
    Auth(#[from] AuthError),

    #[error("timeout: {0}")]
    Timeout(#[from] TimeoutError),

    #[error("protocol error: {0}")]
    Protocol(#[from] ProtocolError),

    #[error("I/O error: {0}")]
    Io(#[from] std::io::Error),

    #[error("client is disconnected")]
    Disconnected,

    #[error("action response channel closed")]
    ResponseChannelClosed,

    /// the action reached the wire, but no definitive response was received
    #[error("outcome unknown for AMI action {action_id}: it may have been executed")]
    OutcomeUnknown { action_id: String },

    #[error("AMI in-flight action limit exceeded ({limit})")]
    InFlightLimitExceeded { limit: usize },

    #[error("AMI event list {action_id} exceeded the {limit}-event limit")]
    EventListEventLimitExceeded { action_id: String, limit: usize },

    #[error("AMI event list {action_id} exceeded the {limit}-byte limit")]
    EventListByteLimitExceeded { action_id: String, limit: usize },

    #[error("AMI event-list in-flight action limit exceeded ({limit})")]
    EventListInFlightLimitExceeded { limit: usize },

    #[error(
        "AMI event lists exceeded the connection-wide {limit}-byte limit while collecting {action_id}"
    )]
    EventListConnectionByteLimitExceeded { action_id: String, limit: usize },

    #[error("AMI event list {action_id} was cancelled by Asterisk")]
    EventListCancelled { action_id: String },

    #[error("invalid configuration: {details}")]
    InvalidConfig { details: String },
}

pub type Result<T> = std::result::Result<T, AmiError>;