#[derive(Clone)]
pub(crate) struct Upstream {
pub source: moq_mux::Source,
pub broadcast: moq_net::broadcast::Consumer,
}
impl Upstream {
pub fn bind(&self, rel: Option<&moq_net::path::RelativeOwned>) -> moq_mux::Result<moq_mux::Binding> {
if self.source.resolve_reference(rel) == self.source.resolve_reference(None) {
Ok(moq_mux::Binding::new(self.broadcast.clone()))
} else {
self.source.bind(rel)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn self_references_keep_the_catalog_broadcast_after_replacement() {
let (origin, driver) = moq_net::origin::Producer::new(moq_net::origin::Config::default());
let driver = tokio::spawn(moq_net::time::run(driver));
let old = origin.create_broadcast("a/live").unwrap();
let source = moq_mux::Source::new(origin.consume(), "a/live");
let upstream = Upstream {
source,
broadcast: old.consume(),
};
drop(old);
let _replacement = origin.create_broadcast("a/live").unwrap();
for _ in 0..10 {
tokio::task::yield_now().await;
}
assert!(!upstream.source.broadcast().await.unwrap().is_closed());
for reference in [None, Some(""), Some("live"), Some("./live"), Some("../a/live")] {
let rel = reference.map(|value| moq_net::path::Relative::new(value).to_owned());
let bound = upstream.bind(rel.as_ref()).unwrap().broadcast().await.unwrap();
assert!(
bound.is_closed(),
"{reference:?} must keep the original catalog broadcast"
);
}
driver.abort();
}
}