use std::ops::{Deref, DerefMut};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
pub trait CatalogExt: Serialize + DeserializeOwned + Default + Clone + Send + 'static {}
impl CatalogExt for () {}
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq)]
#[serde(bound(serialize = "E: Serialize", deserialize = "E: DeserializeOwned"))]
pub struct Catalog<E: CatalogExt = ()> {
#[serde(default)]
pub video: hang::catalog::Video,
#[serde(default)]
pub audio: hang::catalog::Audio,
#[serde(flatten)]
pub ext: E,
}
impl<E: CatalogExt> Catalog<E> {
pub(crate) fn media(&self) -> hang::Catalog {
hang::Catalog {
video: self.video.clone(),
audio: self.audio.clone(),
}
}
}
impl<E: CatalogExt> Deref for Catalog<E> {
type Target = E;
fn deref(&self) -> &E {
&self.ext
}
}
impl<E: CatalogExt> DerefMut for Catalog<E> {
fn deref_mut(&mut self) -> &mut E {
&mut self.ext
}
}
#[cfg(test)]
mod test {
use std::task::Poll;
use serde::{Deserialize, Serialize};
use super::*;
#[derive(Serialize, Deserialize, Clone, Default, PartialEq, Debug)]
struct Scte35Ext {
#[serde(skip_serializing_if = "Option::is_none")]
scte35: Option<Scte35>,
}
#[derive(Serialize, Deserialize, Clone, Default, PartialEq, Debug)]
struct Scte35 {
splice_id: u32,
}
impl CatalogExt for Scte35Ext {}
#[test]
fn extension_roundtrip() {
let mut broadcast = moq_net::Broadcast::new().produce();
let mut producer =
crate::catalog::Producer::with_catalog(&mut broadcast, Catalog::<Scte35Ext>::default()).unwrap();
let mut consumer = producer.consume().unwrap();
producer.lock().audio.renditions.insert(
"audio0".to_string(),
hang::catalog::AudioConfig::new(hang::catalog::AudioCodec::Opus, 48_000, 2),
);
producer.lock().scte35 = Some(Scte35 { splice_id: 42 });
let waiter = kio::Waiter::noop();
let mut latest = None;
while let Poll::Ready(Ok(Some(catalog))) = consumer.poll_next(&waiter) {
latest = Some(catalog);
}
let catalog = latest.expect("catalog published");
assert!(catalog.audio.renditions.contains_key("audio0"));
assert_eq!(catalog.scte35, Some(Scte35 { splice_id: 42 }));
}
}