webrtc_constraints/constraints/
advanced.rs

1use std::{
2    iter::FromIterator,
3    ops::{Deref, DerefMut},
4};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::{
10    MediaTrackConstraint, MediaTrackConstraintResolutionStrategy, MediaTrackSupportedConstraints,
11    ResolvedMediaTrackConstraint, SanitizedMediaTrackConstraint,
12};
13
14use super::constraint_set::GenericMediaTrackConstraintSet;
15
16/// Advanced media track constraints that contain sets of either bare values or constraints.
17pub type AdvancedMediaTrackConstraints = GenericAdvancedMediaTrackConstraints<MediaTrackConstraint>;
18
19/// Advanced media track constraints that contain sets of constraints (both, empty and non-empty).
20pub type ResolvedAdvancedMediaTrackConstraints =
21    GenericAdvancedMediaTrackConstraints<ResolvedMediaTrackConstraint>;
22
23/// Advanced media track constraints that contain sets of only non-empty constraints.
24pub type SanitizedAdvancedMediaTrackConstraints =
25    GenericAdvancedMediaTrackConstraints<SanitizedMediaTrackConstraint>;
26
27/// The list of advanced constraint sets for a [`MediaStreamTrack`][media_stream_track] object.
28///
29/// # W3C Spec Compliance
30///
31/// Corresponds to [`ResolvedMediaTrackConstraints.advanced`][media_track_constraints_advanced]
32/// from the W3C ["Media Capture and Streams"][media_capture_and_streams_spec] spec.
33///
34/// [media_stream_track]: https://www.w3.org/TR/mediacapture-streams/#dom-mediastreamtrack
35/// [media_track_constraints_advanced]: https://www.w3.org/TR/mediacapture-streams/#dom-mediatrackconstraints-advanced
36/// [media_capture_and_streams_spec]: https://www.w3.org/TR/mediacapture-streams/
37#[derive(Debug, Clone, Eq, PartialEq)]
38#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
39#[cfg_attr(feature = "serde", serde(transparent))]
40pub struct GenericAdvancedMediaTrackConstraints<T>(Vec<GenericMediaTrackConstraintSet<T>>);
41
42impl<T> GenericAdvancedMediaTrackConstraints<T> {
43    pub fn new(constraints: Vec<GenericMediaTrackConstraintSet<T>>) -> Self {
44        Self(constraints)
45    }
46
47    pub fn into_inner(self) -> Vec<GenericMediaTrackConstraintSet<T>> {
48        self.0
49    }
50}
51
52impl<T> Deref for GenericAdvancedMediaTrackConstraints<T> {
53    type Target = Vec<GenericMediaTrackConstraintSet<T>>;
54
55    fn deref(&self) -> &Self::Target {
56        &self.0
57    }
58}
59
60impl<T> DerefMut for GenericAdvancedMediaTrackConstraints<T> {
61    fn deref_mut(&mut self) -> &mut Self::Target {
62        &mut self.0
63    }
64}
65
66impl<T> Default for GenericAdvancedMediaTrackConstraints<T> {
67    fn default() -> Self {
68        Self(Default::default())
69    }
70}
71
72impl<T> FromIterator<GenericMediaTrackConstraintSet<T>>
73    for GenericAdvancedMediaTrackConstraints<T>
74{
75    fn from_iter<I>(iter: I) -> Self
76    where
77        I: IntoIterator<Item = GenericMediaTrackConstraintSet<T>>,
78    {
79        Self::new(iter.into_iter().collect())
80    }
81}
82
83impl<T> IntoIterator for GenericAdvancedMediaTrackConstraints<T> {
84    type Item = GenericMediaTrackConstraintSet<T>;
85    type IntoIter = std::vec::IntoIter<GenericMediaTrackConstraintSet<T>>;
86
87    fn into_iter(self) -> Self::IntoIter {
88        self.0.into_iter()
89    }
90}
91
92impl AdvancedMediaTrackConstraints {
93    pub fn to_resolved(&self) -> ResolvedAdvancedMediaTrackConstraints {
94        self.clone().into_resolved()
95    }
96
97    pub fn into_resolved(self) -> ResolvedAdvancedMediaTrackConstraints {
98        let strategy = MediaTrackConstraintResolutionStrategy::BareToExact;
99        ResolvedAdvancedMediaTrackConstraints::from_iter(
100            self.into_iter()
101                .map(|constraint_set| constraint_set.into_resolved(strategy)),
102        )
103    }
104}
105
106impl ResolvedAdvancedMediaTrackConstraints {
107    pub fn to_sanitized(
108        &self,
109        supported_constraints: &MediaTrackSupportedConstraints,
110    ) -> SanitizedAdvancedMediaTrackConstraints {
111        self.clone().into_sanitized(supported_constraints)
112    }
113
114    pub fn into_sanitized(
115        self,
116        supported_constraints: &MediaTrackSupportedConstraints,
117    ) -> SanitizedAdvancedMediaTrackConstraints {
118        SanitizedAdvancedMediaTrackConstraints::from_iter(
119            self.into_iter()
120                .map(|constraint_set| constraint_set.into_sanitized(supported_constraints))
121                .filter(|constraint_set| !constraint_set.is_empty()),
122        )
123    }
124}
125
126#[cfg(feature = "serde")]
127#[cfg(test)]
128mod serde_tests {
129    use crate::{property::all::name::*, MediaTrackConstraintSet};
130
131    use super::*;
132
133    #[test]
134    fn serialize_default() {
135        let advanced = AdvancedMediaTrackConstraints::default();
136        let actual = serde_json::to_value(advanced).unwrap();
137        let expected = serde_json::json!([]);
138
139        assert_eq!(actual, expected);
140    }
141
142    #[test]
143    fn deserialize_default() {
144        let json = serde_json::json!([]);
145        let actual: AdvancedMediaTrackConstraints = serde_json::from_value(json).unwrap();
146        let expected = AdvancedMediaTrackConstraints::default();
147
148        assert_eq!(actual, expected);
149    }
150
151    #[test]
152    fn serialize() {
153        let advanced =
154            AdvancedMediaTrackConstraints::new(vec![MediaTrackConstraintSet::from_iter([
155                (&DEVICE_ID, "device-id".into()),
156                (&AUTO_GAIN_CONTROL, true.into()),
157                (&CHANNEL_COUNT, 2.into()),
158                (&LATENCY, 0.123.into()),
159            ])]);
160        let actual = serde_json::to_value(advanced).unwrap();
161        let expected = serde_json::json!([
162            {
163                "deviceId": "device-id".to_owned(),
164                "autoGainControl": true,
165                "channelCount": 2,
166                "latency": 0.123,
167            }
168        ]);
169
170        assert_eq!(actual, expected);
171    }
172
173    #[test]
174    fn deserialize() {
175        let json = serde_json::json!([
176            {
177                "deviceId": "device-id".to_owned(),
178                "autoGainControl": true,
179                "channelCount": 2,
180                "latency": 0.123,
181            }
182        ]);
183        let actual: AdvancedMediaTrackConstraints = serde_json::from_value(json).unwrap();
184        let expected =
185            AdvancedMediaTrackConstraints::new(vec![MediaTrackConstraintSet::from_iter([
186                (&DEVICE_ID, "device-id".into()),
187                (&AUTO_GAIN_CONTROL, true.into()),
188                (&CHANNEL_COUNT, 2.into()),
189                (&LATENCY, 0.123.into()),
190            ])]);
191
192        assert_eq!(actual, expected);
193    }
194}