use std::str::FromStr;
use freeswitch_types::{BridgeDialString, DialString};
use crate::fields::processing_parts;
use crate::message::new_channel_name;
pub(super) struct DialplanContext {
pub(super) from: String,
pub(super) from_name: Option<String>,
pub(super) from_number: Option<String>,
pub(super) to: String,
pub(super) context: String,
}
pub(super) fn parse_dialplan_context(detail: &str) -> Option<&str> {
let rest = detail.strip_prefix("parsing [")?;
let bracket_end = rest.find(']')?;
let inner = &rest[..bracket_end];
let arrow = inner.find("->")?;
Some(&inner[..arrow])
}
pub(super) fn parse_processing_line(msg: &str) -> Option<DialplanContext> {
let parts = processing_parts(msg)?;
Some(DialplanContext {
from: msg[parts.head].to_string(),
from_name: parts.name.map(|r| msg[r].to_string()),
from_number: parts.number.map(|r| msg[r].to_string()),
to: msg[parts.dest].to_string(),
context: msg[parts.context].to_string(),
})
}
pub(super) fn parse_new_channel(detail: &str) -> Option<&str> {
new_channel_name(detail)
}
pub(super) fn parse_hangup(detail: &str) -> Option<&str> {
let start = detail.rfind('[')?;
let end = detail[start..].find(']')?;
Some(&detail[start + 1..start + end])
}
pub fn parse_bridge_args(arguments: &str) -> Option<BridgeInfo> {
let dial = BridgeDialString::from_str(arguments).ok()?;
let first_ep = dial.groups().first()?.first()?;
let origination_uuid = first_ep
.variables()
.and_then(|v| v.get("origination_uuid"))
.or_else(|| dial.variables().and_then(|v| v.get("origination_uuid")))
.map(|s| s.to_string());
let mut bare = first_ep.clone();
bare.set_variables(None);
let target_channel = bare.to_string();
Some(BridgeInfo {
origination_uuid,
target_channel,
})
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct BridgeInfo {
pub origination_uuid: Option<String>,
pub target_channel: String,
}