use crate::client::AriClient;
use crate::error::Result;
use crate::event::{AriEvent, AriMessage, Bridge, Channel};
use crate::resources::bridge::BridgeHandle;
use crate::resources::channel::{ChannelHandle, OriginateParams};
use asterisk_rs_core::event::FilteredSubscription;
fn generate_pending_id(prefix: &str) -> String {
format!("{prefix}-pending-{}", uuid::Uuid::new_v4().simple())
}
fn event_matches_channel_id(event: &AriEvent, id: &str) -> bool {
event.channel_ids().contains(&id)
}
fn event_matches_bridge_id(event: &AriEvent, id: &str) -> bool {
event.bridge_ids().contains(&id)
}
fn event_playback_id(event: &AriEvent) -> Option<&str> {
event.playback_ids().first().copied()
}
#[derive(Debug)]
pub struct PendingChannel {
id: String,
client: AriClient,
events: FilteredSubscription<AriMessage>,
}
impl PendingChannel {
pub(crate) fn new(client: AriClient) -> Self {
let id = generate_pending_id("channel");
let filter_id = id.clone();
let events =
client.subscribe_filtered(move |msg| event_matches_channel_id(&msg.event, &filter_id));
Self { id, client, events }
}
pub fn id(&self) -> &str {
&self.id
}
pub async fn originate(
self,
mut params: OriginateParams,
) -> Result<(ChannelHandle, FilteredSubscription<AriMessage>)> {
params.channel_id = Some(self.id.clone());
let channel: Channel = self.client.post("/channels", ¶ms).await?;
let handle = ChannelHandle::new(channel.id, self.client);
Ok((handle, self.events))
}
pub fn events_mut(&mut self) -> &mut FilteredSubscription<AriMessage> {
&mut self.events
}
}
#[derive(Debug)]
pub struct PendingBridge {
id: String,
client: AriClient,
events: FilteredSubscription<AriMessage>,
}
impl PendingBridge {
pub(crate) fn new(client: AriClient) -> Self {
let id = generate_pending_id("bridge");
let filter_id = id.clone();
let events =
client.subscribe_filtered(move |msg| event_matches_bridge_id(&msg.event, &filter_id));
Self { id, client, events }
}
pub fn id(&self) -> &str {
&self.id
}
pub async fn create(
self,
bridge_type: &str,
) -> Result<(BridgeHandle, FilteredSubscription<AriMessage>)> {
let bridge: Bridge = self
.client
.post(
"/bridges",
&serde_json::json!({ "bridgeId": self.id, "type": bridge_type }),
)
.await?;
let handle = BridgeHandle::new(bridge.id, self.client);
Ok((handle, self.events))
}
pub fn events_mut(&mut self) -> &mut FilteredSubscription<AriMessage> {
&mut self.events
}
}
#[derive(Debug)]
pub struct PendingPlayback {
id: String,
events: FilteredSubscription<AriMessage>,
}
impl PendingPlayback {
pub(crate) fn new(client: &AriClient) -> Self {
let id = generate_pending_id("playback");
let filter_id = id.clone();
let events = client.subscribe_filtered(move |msg| {
event_playback_id(&msg.event).is_some_and(|pb_id| pb_id == filter_id)
});
Self { id, events }
}
pub fn id(&self) -> &str {
&self.id
}
pub fn into_events(self) -> FilteredSubscription<AriMessage> {
self.events
}
}