use shared::TransportMessage;
use std::any::Any;
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Packet {
Rtp(rtp::Packet),
Rtcp(Vec<Box<dyn rtcp::Packet>>),
}
#[derive(Clone)]
#[non_exhaustive]
pub enum Attribute {
RecoveredByFec,
Retransmission,
DeliverToApplication,
TargetBitrateChanged {
bits_per_second: f64,
},
Custom(Arc<dyn Any + Send + Sync>),
}
impl std::fmt::Debug for Attribute {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::RecoveredByFec => f.write_str("RecoveredByFec"),
Self::Retransmission => f.write_str("Retransmission"),
Self::DeliverToApplication => f.write_str("DeliverToApplication"),
Self::TargetBitrateChanged { bits_per_second } => f
.debug_struct("TargetBitrateChanged")
.field("bits_per_second", bits_per_second)
.finish(),
Self::Custom(_) => f.write_str("Custom(..)"),
}
}
}
#[derive(Clone, Debug)]
pub struct AttributedPacket {
pub attributes: Vec<Attribute>,
pub packet: Packet,
}
impl AttributedPacket {
pub fn new(packet: Packet) -> Self {
Self {
attributes: Vec::new(),
packet,
}
}
pub fn with(mut self, attribute: Attribute) -> Self {
self.attributes.push(attribute);
self
}
pub fn add(&mut self, attribute: Attribute) -> &mut Self {
self.attributes.push(attribute);
self
}
pub fn has(&self, attribute: &Attribute) -> bool {
let wanted = std::mem::discriminant(attribute);
self.attributes
.iter()
.any(|held| std::mem::discriminant(held) == wanted)
}
pub fn get(&self, attribute: &Attribute) -> Option<&Attribute> {
let wanted = std::mem::discriminant(attribute);
self.attributes
.iter()
.find(|held| std::mem::discriminant(*held) == wanted)
}
pub fn custom<T: Any + Send + Sync>(&self) -> Option<&T> {
self.attributes
.iter()
.find_map(|attribute| match attribute {
Attribute::Custom(value) => value.downcast_ref::<T>(),
_ => None,
})
}
}
impl From<Packet> for AttributedPacket {
fn from(packet: Packet) -> Self {
Self::new(packet)
}
}
pub type TaggedPacket = TransportMessage<AttributedPacket>;