webrtc_constraints/constraints/
mandatory.rs1use std::{
2 iter::FromIterator,
3 ops::{Deref, DerefMut},
4};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::{
10 MediaTrackConstraint, MediaTrackConstraintResolutionStrategy, MediaTrackProperty,
11 MediaTrackSupportedConstraints, ResolvedMediaTrackConstraint, SanitizedMediaTrackConstraint,
12};
13
14use super::constraint_set::GenericMediaTrackConstraintSet;
15
16pub type MandatoryMediaTrackConstraints =
29 GenericMandatoryMediaTrackConstraints<MediaTrackConstraint>;
30
31pub type ResolvedMandatoryMediaTrackConstraints =
45 GenericMandatoryMediaTrackConstraints<ResolvedMediaTrackConstraint>;
46
47pub type SanitizedMandatoryMediaTrackConstraints =
49 GenericMandatoryMediaTrackConstraints<SanitizedMediaTrackConstraint>;
50
51#[derive(Debug, Clone, Eq, PartialEq)]
62#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63#[cfg_attr(feature = "serde", serde(transparent))]
64pub struct GenericMandatoryMediaTrackConstraints<T>(GenericMediaTrackConstraintSet<T>);
65
66impl<T> GenericMandatoryMediaTrackConstraints<T> {
67 pub fn new(constraints: GenericMediaTrackConstraintSet<T>) -> Self {
68 Self(constraints)
69 }
70
71 pub fn into_inner(self) -> GenericMediaTrackConstraintSet<T> {
72 self.0
73 }
74}
75
76impl GenericMandatoryMediaTrackConstraints<ResolvedMediaTrackConstraint> {
77 pub fn basic(&self) -> GenericMediaTrackConstraintSet<ResolvedMediaTrackConstraint> {
78 self.basic_or_required(false)
79 }
80
81 pub fn required(&self) -> GenericMediaTrackConstraintSet<ResolvedMediaTrackConstraint> {
82 self.basic_or_required(true)
83 }
84
85 fn basic_or_required(
86 &self,
87 required: bool,
88 ) -> GenericMediaTrackConstraintSet<ResolvedMediaTrackConstraint> {
89 GenericMediaTrackConstraintSet::new(
90 self.0
91 .iter()
92 .filter_map(|(property, constraint)| {
93 if constraint.is_required() == required {
94 Some((property.clone(), constraint.clone()))
95 } else {
96 None
97 }
98 })
99 .collect(),
100 )
101 }
102}
103
104impl<T> Deref for GenericMandatoryMediaTrackConstraints<T> {
105 type Target = GenericMediaTrackConstraintSet<T>;
106
107 fn deref(&self) -> &Self::Target {
108 &self.0
109 }
110}
111
112impl<T> DerefMut for GenericMandatoryMediaTrackConstraints<T> {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 &mut self.0
115 }
116}
117
118impl<T> Default for GenericMandatoryMediaTrackConstraints<T> {
119 fn default() -> Self {
120 Self(Default::default())
121 }
122}
123
124impl<T, U> FromIterator<(U, T)> for GenericMandatoryMediaTrackConstraints<T>
125where
126 U: Into<MediaTrackProperty>,
127{
128 fn from_iter<I>(iter: I) -> Self
129 where
130 I: IntoIterator<Item = (U, T)>,
131 {
132 Self::new(iter.into_iter().map(|(k, v)| (k.into(), v)).collect())
133 }
134}
135
136impl<T> IntoIterator for GenericMandatoryMediaTrackConstraints<T> {
137 type Item = (MediaTrackProperty, T);
138 type IntoIter = indexmap::map::IntoIter<MediaTrackProperty, T>;
139
140 fn into_iter(self) -> Self::IntoIter {
141 self.0.into_iter()
142 }
143}
144
145impl MandatoryMediaTrackConstraints {
146 pub fn to_resolved(&self) -> ResolvedMandatoryMediaTrackConstraints {
147 self.clone().into_resolved()
148 }
149
150 pub fn into_resolved(self) -> ResolvedMandatoryMediaTrackConstraints {
151 let strategy = MediaTrackConstraintResolutionStrategy::BareToIdeal;
152 ResolvedMandatoryMediaTrackConstraints::new(self.0.into_resolved(strategy))
153 }
154}
155
156impl ResolvedMandatoryMediaTrackConstraints {
157 pub fn to_sanitized(
158 &self,
159 supported_constraints: &MediaTrackSupportedConstraints,
160 ) -> SanitizedMandatoryMediaTrackConstraints {
161 self.clone().into_sanitized(supported_constraints)
162 }
163
164 pub fn into_sanitized(
165 self,
166 supported_constraints: &MediaTrackSupportedConstraints,
167 ) -> SanitizedMandatoryMediaTrackConstraints {
168 SanitizedMandatoryMediaTrackConstraints::new(self.0.into_sanitized(supported_constraints))
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use crate::{
175 property::all::name::*, ResolvedMediaTrackConstraintSet, ResolvedValueConstraint,
176 ResolvedValueRangeConstraint,
177 };
178
179 use super::*;
180
181 #[test]
182 fn basic() {
183 let mandatory = ResolvedMandatoryMediaTrackConstraints::new(
184 ResolvedMediaTrackConstraintSet::from_iter([
185 (
186 &DEVICE_ID,
187 ResolvedValueConstraint::default()
188 .exact("device-id".to_owned())
189 .into(),
190 ),
191 (
192 &AUTO_GAIN_CONTROL,
193 ResolvedValueConstraint::default().ideal(true).into(),
194 ),
195 (
196 &CHANNEL_COUNT,
197 ResolvedValueRangeConstraint::default()
198 .exact(2)
199 .ideal(3)
200 .into(),
201 ),
202 ]),
203 );
204
205 let actual = mandatory.basic();
206 let expected = ResolvedMediaTrackConstraintSet::from_iter([(
207 &AUTO_GAIN_CONTROL,
208 ResolvedValueConstraint::default().ideal(true).into(),
209 )]);
210
211 assert_eq!(actual, expected);
212 }
213
214 #[test]
215 fn required() {
216 let mandatory = ResolvedMandatoryMediaTrackConstraints::new(
217 ResolvedMediaTrackConstraintSet::from_iter([
218 (
219 &DEVICE_ID,
220 ResolvedValueConstraint::default()
221 .exact("device-id".to_owned())
222 .into(),
223 ),
224 (
225 &AUTO_GAIN_CONTROL,
226 ResolvedValueConstraint::default().ideal(true).into(),
227 ),
228 (
229 &CHANNEL_COUNT,
230 ResolvedValueRangeConstraint::default()
231 .exact(2)
232 .ideal(3)
233 .into(),
234 ),
235 ]),
236 );
237
238 let actual = mandatory.required();
239 let expected = ResolvedMediaTrackConstraintSet::from_iter([
240 (
241 &DEVICE_ID,
242 ResolvedValueConstraint::default()
243 .exact("device-id".to_owned())
244 .into(),
245 ),
246 (
247 &CHANNEL_COUNT,
248 ResolvedValueRangeConstraint::default()
249 .exact(2)
250 .ideal(3)
251 .into(),
252 ),
253 ]);
254
255 assert_eq!(actual, expected);
256 }
257}
258
259#[cfg(feature = "serde")]
260#[cfg(test)]
261mod serde_tests {
262 use crate::{property::all::name::*, MediaTrackConstraintSet};
263
264 use super::*;
265
266 #[test]
267 fn serialize_default() {
268 let mandatory = MandatoryMediaTrackConstraints::default();
269 let actual = serde_json::to_value(mandatory).unwrap();
270 let expected = serde_json::json!({});
271
272 assert_eq!(actual, expected);
273 }
274
275 #[test]
276 fn deserialize_default() {
277 let json = serde_json::json!({});
278 let actual: MandatoryMediaTrackConstraints = serde_json::from_value(json).unwrap();
279 let expected = MandatoryMediaTrackConstraints::default();
280
281 assert_eq!(actual, expected);
282 }
283
284 #[test]
285 fn serialize() {
286 let mandatory = MandatoryMediaTrackConstraints::new(MediaTrackConstraintSet::from_iter([
287 (&DEVICE_ID, "device-id".into()),
288 (&AUTO_GAIN_CONTROL, true.into()),
289 (&CHANNEL_COUNT, 2.into()),
290 (&LATENCY, 0.123.into()),
291 ]));
292 let actual = serde_json::to_value(mandatory).unwrap();
293 let expected = serde_json::json!(
294 {
295 "deviceId": "device-id".to_owned(),
296 "autoGainControl": true,
297 "channelCount": 2,
298 "latency": 0.123,
299 }
300 );
301
302 assert_eq!(actual, expected);
303 }
304
305 #[test]
306 fn deserialize() {
307 let json = serde_json::json!(
308 {
309 "deviceId": "device-id".to_owned(),
310 "autoGainControl": true,
311 "channelCount": 2,
312 "latency": 0.123,
313 }
314 );
315 let actual: MandatoryMediaTrackConstraints = serde_json::from_value(json).unwrap();
316 let expected = MandatoryMediaTrackConstraints::new(MediaTrackConstraintSet::from_iter([
317 (&DEVICE_ID, "device-id".into()),
318 (&AUTO_GAIN_CONTROL, true.into()),
319 (&CHANNEL_COUNT, 2.into()),
320 (&LATENCY, 0.123.into()),
321 ]));
322
323 assert_eq!(actual, expected);
324 }
325}