webrtc_constraints/capabilities/
track.rs1use std::{
2 collections::HashMap,
3 iter::FromIterator,
4 ops::{Deref, DerefMut},
5};
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use crate::{MediaTrackCapability, MediaTrackProperty};
11
12#[derive(Debug, Clone, Default, PartialEq)]
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30#[cfg_attr(feature = "serde", serde(transparent))]
31pub struct MediaTrackCapabilities(HashMap<MediaTrackProperty, MediaTrackCapability>);
32
33impl MediaTrackCapabilities {
34 pub fn new(capabilities: HashMap<MediaTrackProperty, MediaTrackCapability>) -> Self {
36 Self(capabilities)
37 }
38
39 pub fn into_inner(self) -> HashMap<MediaTrackProperty, MediaTrackCapability> {
41 self.0
42 }
43}
44
45impl Deref for MediaTrackCapabilities {
46 type Target = HashMap<MediaTrackProperty, MediaTrackCapability>;
47
48 fn deref(&self) -> &Self::Target {
49 &self.0
50 }
51}
52
53impl DerefMut for MediaTrackCapabilities {
54 fn deref_mut(&mut self) -> &mut Self::Target {
55 &mut self.0
56 }
57}
58
59impl<T> FromIterator<(T, MediaTrackCapability)> for MediaTrackCapabilities
60where
61 T: Into<MediaTrackProperty>,
62{
63 fn from_iter<I>(iter: I) -> Self
64 where
65 I: IntoIterator<Item = (T, MediaTrackCapability)>,
66 {
67 Self::new(iter.into_iter().map(|(k, v)| (k.into(), v)).collect())
68 }
69}
70
71impl IntoIterator for MediaTrackCapabilities {
72 type Item = (MediaTrackProperty, MediaTrackCapability);
73 type IntoIter = std::collections::hash_map::IntoIter<MediaTrackProperty, MediaTrackCapability>;
74
75 fn into_iter(self) -> Self::IntoIter {
76 self.0.into_iter()
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use crate::property::all::name::*;
83
84 use super::*;
85
86 type Subject = MediaTrackCapabilities;
87
88 #[test]
89 fn into_inner() {
90 let hash_map = HashMap::from_iter([
91 (DEVICE_ID.clone(), "device-id".into()),
92 (AUTO_GAIN_CONTROL.clone(), true.into()),
93 (CHANNEL_COUNT.clone(), (12..=34).into()),
94 (LATENCY.clone(), (1.2..=3.4).into()),
95 ]);
96
97 let subject = Subject::new(hash_map.clone());
98
99 let actual = subject.into_inner();
100
101 let expected = hash_map;
102
103 assert_eq!(actual, expected);
104 }
105
106 #[test]
107 fn into_iter() {
108 let hash_map = HashMap::from_iter([
109 (DEVICE_ID.clone(), "device-id".into()),
110 (AUTO_GAIN_CONTROL.clone(), true.into()),
111 (CHANNEL_COUNT.clone(), (12..=34).into()),
112 (LATENCY.clone(), (1.2..=3.4).into()),
113 ]);
114
115 let subject = Subject::new(hash_map.clone());
116
117 let actual: HashMap<_, _> = subject.into_iter().collect();
118
119 let expected = hash_map;
120
121 assert_eq!(actual, expected);
122 }
123
124 #[test]
125 fn deref_and_deref_mut() {
126 let mut subject = Subject::default();
127
128 subject.insert(DEVICE_ID.clone(), "device-id".into());
130
131 assert!(subject.contains_key(&DEVICE_ID));
133 }
134}
135
136#[cfg(feature = "serde")]
137#[cfg(test)]
138mod serde_tests {
139 use crate::{macros::test_serde_symmetry, property::all::name::*};
140
141 use super::*;
142
143 type Subject = MediaTrackCapabilities;
144
145 #[test]
146 fn default() {
147 let subject = Subject::default();
148 let json = serde_json::json!({});
149
150 test_serde_symmetry!(subject: subject, json: json);
151 }
152
153 #[test]
154 fn customized() {
155 let subject = Subject::from_iter([
156 (&DEVICE_ID, "device-id".into()),
157 (&AUTO_GAIN_CONTROL, true.into()),
158 (&CHANNEL_COUNT, (12..=34).into()),
159 (&LATENCY, (1.2..=3.4).into()),
160 ]);
161 let json = serde_json::json!({
162 "deviceId": "device-id".to_owned(),
163 "autoGainControl": true,
164 "channelCount": { "min": 12, "max": 34 },
165 "latency": { "min": 1.2, "max": 3.4 },
166 });
167
168 test_serde_symmetry!(subject: subject, json: json);
169 }
170}