use std::time::Duration;
use async_trait::async_trait;
use tokio::sync::mpsc;
use crate::api::callback_peer::{CallHandler, CallHandlerDecision};
use crate::api::incoming::{IncomingCall, IncomingCallGuard};
pub struct AutoAnswerHandler;
#[async_trait]
impl CallHandler for AutoAnswerHandler {
async fn on_incoming_call(&self, _call: IncomingCall) -> CallHandlerDecision {
CallHandlerDecision::Accept
}
}
pub struct RejectAllHandler {
pub status: u16,
pub reason: String,
}
impl Default for RejectAllHandler {
fn default() -> Self {
Self {
status: 486,
reason: "Busy Here".into(),
}
}
}
impl RejectAllHandler {
pub fn new(status: u16, reason: impl Into<String>) -> Self {
Self {
status,
reason: reason.into(),
}
}
}
#[async_trait]
impl CallHandler for RejectAllHandler {
async fn on_incoming_call(&self, _call: IncomingCall) -> CallHandlerDecision {
CallHandlerDecision::Reject {
status: self.status,
reason: self.reason.clone(),
}
}
}
#[derive(Debug, Clone)]
pub enum RoutingAction {
Accept,
Reject {
status: u16,
reason: String,
},
Redirect(String),
}
#[derive(Debug, Clone)]
pub struct RoutingRule {
pub pattern: String,
pub action: RoutingAction,
}
pub struct RoutingHandler {
rules: Vec<RoutingRule>,
default_action: RoutingAction,
}
impl RoutingHandler {
pub fn new() -> Self {
Self {
rules: Vec::new(),
default_action: RoutingAction::Reject {
status: 404,
reason: "Not Found".into(),
},
}
}
pub fn with_rule(mut self, pattern: impl Into<String>, action: RoutingAction) -> Self {
self.rules.push(RoutingRule {
pattern: pattern.into(),
action,
});
self
}
pub fn with_default(mut self, action: RoutingAction) -> Self {
self.default_action = action;
self
}
}
impl Default for RoutingHandler {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl CallHandler for RoutingHandler {
async fn on_incoming_call(&self, call: IncomingCall) -> CallHandlerDecision {
let action = self
.rules
.iter()
.find(|r| call.to.contains(&r.pattern))
.map(|r| &r.action)
.unwrap_or(&self.default_action);
match action {
RoutingAction::Accept => CallHandlerDecision::Accept,
RoutingAction::Reject { status, reason } => CallHandlerDecision::Reject {
status: *status,
reason: reason.clone(),
},
RoutingAction::Redirect(target) => CallHandlerDecision::Redirect(target.clone()),
}
}
}
pub struct QueueHandler {
tx: mpsc::Sender<IncomingCallGuard>,
defer_timeout: Duration,
}
impl QueueHandler {
pub fn new(
buffer: usize,
defer_timeout: Duration,
) -> (Self, mpsc::Receiver<IncomingCallGuard>) {
let (tx, rx) = mpsc::channel(buffer);
(Self { tx, defer_timeout }, rx)
}
}
#[async_trait]
impl CallHandler for QueueHandler {
async fn on_incoming_call(&self, call: IncomingCall) -> CallHandlerDecision {
let guard = call.defer(self.defer_timeout);
match self.tx.send(guard).await {
Ok(()) => {
CallHandlerDecision::Accept
}
Err(send_err) => {
let guard = send_err.0;
guard.reject(503, "Service Unavailable");
CallHandlerDecision::Accept
}
}
}
}