use crate::statistics::stats::RTCStatsType;
use crate::statistics::stats::certificate::RTCCertificateStats;
use crate::statistics::stats::codec::RTCCodecStats;
use crate::statistics::stats::data_channel::RTCDataChannelStats;
use crate::statistics::stats::ice_candidate::RTCIceCandidateStats;
use crate::statistics::stats::ice_candidate_pair::RTCIceCandidatePairStats;
use crate::statistics::stats::media::audio_playout::RTCAudioPlayoutStats;
use crate::statistics::stats::media::audio_source::RTCAudioSourceStats;
use crate::statistics::stats::media::video_source::RTCVideoSourceStats;
use crate::statistics::stats::peer_connection::RTCPeerConnectionStats;
use crate::statistics::stats::rtp_stream::received::inbound::RTCInboundRtpStreamStats;
use crate::statistics::stats::rtp_stream::received::remote_inbound::RTCRemoteInboundRtpStreamStats;
use crate::statistics::stats::rtp_stream::sent::outbound::RTCOutboundRtpStreamStats;
use crate::statistics::stats::rtp_stream::sent::remote_outbound::RTCRemoteOutboundRtpStreamStats;
use crate::statistics::stats::transport::RTCTransportStats;
use std::collections::HashMap;
#[derive(Debug)]
pub enum RTCStatsReportEntry {
PeerConnection(RTCPeerConnectionStats),
Transport(RTCTransportStats),
IceCandidatePair(RTCIceCandidatePairStats),
LocalCandidate(RTCIceCandidateStats),
RemoteCandidate(RTCIceCandidateStats),
Certificate(RTCCertificateStats),
Codec(RTCCodecStats),
DataChannel(RTCDataChannelStats),
InboundRtp(RTCInboundRtpStreamStats),
OutboundRtp(RTCOutboundRtpStreamStats),
RemoteInboundRtp(RTCRemoteInboundRtpStreamStats),
RemoteOutboundRtp(RTCRemoteOutboundRtpStreamStats),
AudioSource(RTCAudioSourceStats),
VideoSource(RTCVideoSourceStats),
AudioPlayout(RTCAudioPlayoutStats),
}
impl RTCStatsReportEntry {
pub fn stats_type(&self) -> RTCStatsType {
match self {
RTCStatsReportEntry::PeerConnection(_) => RTCStatsType::PeerConnection,
RTCStatsReportEntry::Transport(_) => RTCStatsType::Transport,
RTCStatsReportEntry::IceCandidatePair(_) => RTCStatsType::CandidatePair,
RTCStatsReportEntry::LocalCandidate(_) => RTCStatsType::LocalCandidate,
RTCStatsReportEntry::RemoteCandidate(_) => RTCStatsType::RemoteCandidate,
RTCStatsReportEntry::Certificate(_) => RTCStatsType::Certificate,
RTCStatsReportEntry::Codec(_) => RTCStatsType::Codec,
RTCStatsReportEntry::DataChannel(_) => RTCStatsType::DataChannel,
RTCStatsReportEntry::InboundRtp(_) => RTCStatsType::InboundRTP,
RTCStatsReportEntry::OutboundRtp(_) => RTCStatsType::OutboundRTP,
RTCStatsReportEntry::RemoteInboundRtp(_) => RTCStatsType::RemoteInboundRTP,
RTCStatsReportEntry::RemoteOutboundRtp(_) => RTCStatsType::RemoteOutboundRTP,
RTCStatsReportEntry::AudioSource(_) => RTCStatsType::MediaSource,
RTCStatsReportEntry::VideoSource(_) => RTCStatsType::MediaSource,
RTCStatsReportEntry::AudioPlayout(_) => RTCStatsType::MediaPlayout,
}
}
pub fn id(&self) -> &str {
match self {
RTCStatsReportEntry::PeerConnection(s) => &s.stats.id,
RTCStatsReportEntry::Transport(s) => &s.stats.id,
RTCStatsReportEntry::IceCandidatePair(s) => &s.stats.id,
RTCStatsReportEntry::LocalCandidate(s) => &s.stats.id,
RTCStatsReportEntry::RemoteCandidate(s) => &s.stats.id,
RTCStatsReportEntry::Certificate(s) => &s.stats.id,
RTCStatsReportEntry::Codec(s) => &s.stats.id,
RTCStatsReportEntry::DataChannel(s) => &s.stats.id,
RTCStatsReportEntry::InboundRtp(s) => {
&s.received_rtp_stream_stats.rtp_stream_stats.stats.id
}
RTCStatsReportEntry::OutboundRtp(s) => {
&s.sent_rtp_stream_stats.rtp_stream_stats.stats.id
}
RTCStatsReportEntry::RemoteInboundRtp(s) => {
&s.received_rtp_stream_stats.rtp_stream_stats.stats.id
}
RTCStatsReportEntry::RemoteOutboundRtp(s) => {
&s.sent_rtp_stream_stats.rtp_stream_stats.stats.id
}
RTCStatsReportEntry::AudioSource(s) => &s.media_source_stats.stats.id,
RTCStatsReportEntry::VideoSource(s) => &s.media_source_stats.stats.id,
RTCStatsReportEntry::AudioPlayout(s) => &s.stats.id,
}
}
}
#[derive(Debug, Default)]
pub struct RTCStatsReport {
entries: HashMap<String, RTCStatsReportEntry>,
order: Vec<String>,
}
impl RTCStatsReport {
pub(crate) fn new(entries: Vec<RTCStatsReportEntry>) -> Self {
let mut map = HashMap::new();
let mut order = Vec::with_capacity(entries.len());
for entry in entries {
let id = entry.id().to_string();
order.push(id.clone());
map.insert(id, entry);
}
Self {
entries: map,
order,
}
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn get(&self, id: &str) -> Option<&RTCStatsReportEntry> {
self.entries.get(id)
}
pub fn contains(&self, id: &str) -> bool {
self.entries.contains_key(id)
}
pub fn iter(&self) -> impl Iterator<Item = &RTCStatsReportEntry> {
self.order.iter().filter_map(|id| self.entries.get(id))
}
pub fn iter_by_type(&self, typ: RTCStatsType) -> impl Iterator<Item = &RTCStatsReportEntry> {
self.iter().filter(move |e| e.stats_type() == typ)
}
pub fn ids(&self) -> impl Iterator<Item = &str> {
self.order.iter().map(|s| s.as_str())
}
pub fn peer_connection(&self) -> Option<&RTCPeerConnectionStats> {
self.get("RTCPeerConnection").and_then(|e| match e {
RTCStatsReportEntry::PeerConnection(s) => Some(s),
_ => None,
})
}
pub fn transport(&self) -> Option<&RTCTransportStats> {
self.entries.values().find_map(|e| match e {
RTCStatsReportEntry::Transport(s) => Some(s),
_ => None,
})
}
pub fn inbound_rtp_streams(&self) -> impl Iterator<Item = &RTCInboundRtpStreamStats> {
self.iter().filter_map(|e| match e {
RTCStatsReportEntry::InboundRtp(s) => Some(s),
_ => None,
})
}
pub fn outbound_rtp_streams(&self) -> impl Iterator<Item = &RTCOutboundRtpStreamStats> {
self.iter().filter_map(|e| match e {
RTCStatsReportEntry::OutboundRtp(s) => Some(s),
_ => None,
})
}
pub fn data_channels(&self) -> impl Iterator<Item = &RTCDataChannelStats> {
self.iter().filter_map(|e| match e {
RTCStatsReportEntry::DataChannel(s) => Some(s),
_ => None,
})
}
pub fn candidate_pairs(&self) -> impl Iterator<Item = &RTCIceCandidatePairStats> {
self.iter().filter_map(|e| match e {
RTCStatsReportEntry::IceCandidatePair(s) => Some(s),
_ => None,
})
}
}