1 use std::{ 2 iter::FromIterator, 3 ops::{Deref, DerefMut}, 4 }; 5 6 #[cfg(feature = "serde")] 7 use serde::{Deserialize, Serialize}; 8 9 use crate::{ 10 MediaTrackConstraint, MediaTrackConstraintResolutionStrategy, MediaTrackSupportedConstraints, 11 ResolvedMediaTrackConstraint, SanitizedMediaTrackConstraint, 12 }; 13 14 use super::constraint_set::GenericMediaTrackConstraintSet; 15 16 /// Advanced media track constraints that contain sets of either bare values or constraints. 17 pub type AdvancedMediaTrackConstraints = GenericAdvancedMediaTrackConstraints<MediaTrackConstraint>; 18 19 /// Advanced media track constraints that contain sets of constraints (both, empty and non-empty). 20 pub type ResolvedAdvancedMediaTrackConstraints = 21 GenericAdvancedMediaTrackConstraints<ResolvedMediaTrackConstraint>; 22 23 /// Advanced media track constraints that contain sets of only non-empty constraints. 24 pub 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))] 40 pub struct GenericAdvancedMediaTrackConstraints<T>(Vec<GenericMediaTrackConstraintSet<T>>); 41 42 impl<T> GenericAdvancedMediaTrackConstraints<T> { new(constraints: Vec<GenericMediaTrackConstraintSet<T>>) -> Self43 pub fn new(constraints: Vec<GenericMediaTrackConstraintSet<T>>) -> Self { 44 Self(constraints) 45 } 46 into_inner(self) -> Vec<GenericMediaTrackConstraintSet<T>>47 pub fn into_inner(self) -> Vec<GenericMediaTrackConstraintSet<T>> { 48 self.0 49 } 50 } 51 52 impl<T> Deref for GenericAdvancedMediaTrackConstraints<T> { 53 type Target = Vec<GenericMediaTrackConstraintSet<T>>; 54 deref(&self) -> &Self::Target55 fn deref(&self) -> &Self::Target { 56 &self.0 57 } 58 } 59 60 impl<T> DerefMut for GenericAdvancedMediaTrackConstraints<T> { deref_mut(&mut self) -> &mut Self::Target61 fn deref_mut(&mut self) -> &mut Self::Target { 62 &mut self.0 63 } 64 } 65 66 impl<T> Default for GenericAdvancedMediaTrackConstraints<T> { default() -> Self67 fn default() -> Self { 68 Self(Default::default()) 69 } 70 } 71 72 impl<T> FromIterator<GenericMediaTrackConstraintSet<T>> 73 for GenericAdvancedMediaTrackConstraints<T> 74 { from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = GenericMediaTrackConstraintSet<T>>,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 83 impl<T> IntoIterator for GenericAdvancedMediaTrackConstraints<T> { 84 type Item = GenericMediaTrackConstraintSet<T>; 85 type IntoIter = std::vec::IntoIter<GenericMediaTrackConstraintSet<T>>; 86 into_iter(self) -> Self::IntoIter87 fn into_iter(self) -> Self::IntoIter { 88 self.0.into_iter() 89 } 90 } 91 92 impl AdvancedMediaTrackConstraints { to_resolved(&self) -> ResolvedAdvancedMediaTrackConstraints93 pub fn to_resolved(&self) -> ResolvedAdvancedMediaTrackConstraints { 94 self.clone().into_resolved() 95 } 96 into_resolved(self) -> ResolvedAdvancedMediaTrackConstraints97 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 106 impl ResolvedAdvancedMediaTrackConstraints { to_sanitized( &self, supported_constraints: &MediaTrackSupportedConstraints, ) -> SanitizedAdvancedMediaTrackConstraints107 pub fn to_sanitized( 108 &self, 109 supported_constraints: &MediaTrackSupportedConstraints, 110 ) -> SanitizedAdvancedMediaTrackConstraints { 111 self.clone().into_sanitized(supported_constraints) 112 } 113 into_sanitized( self, supported_constraints: &MediaTrackSupportedConstraints, ) -> SanitizedAdvancedMediaTrackConstraints114 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)] 128 mod serde_tests { 129 use crate::{property::all::name::*, MediaTrackConstraintSet}; 130 131 use super::*; 132 133 #[test] serialize_default()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] deserialize_default()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] serialize()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] deserialize()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 } 195