use std::sync::Arc;
use crate::consumer::MoqBroadcastConsumer;
use crate::error::MoqError;
use crate::ffi::Task;
use crate::producer::MoqBroadcastProducer;
#[derive(uniffi::Object)]
pub struct MoqOriginProducer {
inner: moq_net::OriginProducer,
}
#[derive(uniffi::Object)]
pub struct MoqOriginConsumer {
inner: moq_net::OriginConsumer,
}
#[derive(uniffi::Object)]
pub struct MoqAnnounced {
task: Task<Announced>,
}
struct Announced {
inner: moq_net::OriginConsumer,
}
impl Announced {
async fn next(&mut self) -> Result<Option<Arc<MoqAnnouncement>>, MoqError> {
loop {
match self.inner.announced().await {
Some((path, Some(broadcast))) => {
return Ok(Some(Arc::new(MoqAnnouncement {
path: path.to_string(),
broadcast: Arc::new(MoqBroadcastConsumer::new(broadcast)),
})));
}
Some((_path, None)) => continue,
None => return Ok(None),
}
}
}
async fn available(&mut self) -> Result<Arc<MoqBroadcastConsumer>, MoqError> {
loop {
match self.inner.announced().await {
Some((_path, Some(broadcast))) => {
return Ok(Arc::new(MoqBroadcastConsumer::new(broadcast)));
}
Some((_path, None)) => continue,
None => return Err(MoqError::Closed),
}
}
}
}
#[derive(uniffi::Object)]
pub struct MoqAnnouncement {
path: String,
broadcast: Arc<MoqBroadcastConsumer>,
}
#[derive(uniffi::Object)]
pub struct MoqAnnouncedBroadcast {
task: Task<Announced>,
}
impl MoqOriginProducer {
pub(crate) fn inner(&self) -> &moq_net::OriginProducer {
&self.inner
}
}
#[uniffi::export]
impl MoqOriginProducer {
#[uniffi::constructor]
pub fn new() -> Arc<Self> {
let _guard = crate::ffi::RUNTIME.enter();
Arc::new(Self {
inner: moq_net::Origin::random().produce(),
})
}
pub fn consume(&self) -> Arc<MoqOriginConsumer> {
let _guard = crate::ffi::RUNTIME.enter();
Arc::new(MoqOriginConsumer {
inner: self.inner.consume(),
})
}
pub fn publish(&self, path: String, broadcast: &MoqBroadcastProducer) -> Result<(), MoqError> {
let _guard = crate::ffi::RUNTIME.enter();
let consumer = broadcast.consume_inner()?;
if !self.inner.publish_broadcast(path.as_str(), consumer) {
return Err(MoqError::Unauthorized);
}
Ok(())
}
}
#[uniffi::export]
impl MoqOriginConsumer {
pub fn announced(&self, prefix: String) -> Result<Arc<MoqAnnounced>, MoqError> {
let _guard = crate::ffi::RUNTIME.enter();
let origin = self.inner.clone().with_root(prefix).ok_or(MoqError::Unauthorized)?;
Ok(Arc::new(MoqAnnounced {
task: Task::new(Announced { inner: origin }),
}))
}
pub fn announced_broadcast(&self, path: String) -> Result<Arc<MoqAnnouncedBroadcast>, MoqError> {
let _guard = crate::ffi::RUNTIME.enter();
let origin = self.inner.clone().with_root(path).ok_or(MoqError::Unauthorized)?;
Ok(Arc::new(MoqAnnouncedBroadcast {
task: Task::new(Announced { inner: origin }),
}))
}
}
#[uniffi::export]
impl MoqAnnounced {
pub async fn next(&self) -> Result<Option<Arc<MoqAnnouncement>>, MoqError> {
self.task.run(|mut state| async move { state.next().await }).await
}
pub fn cancel(&self) {
self.task.cancel();
}
}
#[uniffi::export]
impl MoqAnnouncement {
pub fn path(&self) -> String {
self.path.clone()
}
pub fn broadcast(&self) -> Arc<MoqBroadcastConsumer> {
self.broadcast.clone()
}
}
#[uniffi::export]
impl MoqAnnouncedBroadcast {
pub async fn available(&self) -> Result<Arc<MoqBroadcastConsumer>, MoqError> {
self.task.run(|mut state| async move { state.available().await }).await
}
pub fn cancel(&self) {
self.task.cancel();
}
}