webrtc_constraints/constraints/
constraint_set.rs1use std::{
2 iter::FromIterator,
3 ops::{Deref, DerefMut},
4};
5
6use indexmap::IndexMap;
7
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11use crate::{
12 constraint::SanitizedMediaTrackConstraint, MediaTrackConstraint,
13 MediaTrackConstraintResolutionStrategy, MediaTrackProperty, MediaTrackSupportedConstraints,
14 ResolvedMediaTrackConstraint,
15};
16
17pub type MediaTrackConstraintSet = GenericMediaTrackConstraintSet<MediaTrackConstraint>;
19
20pub type ResolvedMediaTrackConstraintSet =
22 GenericMediaTrackConstraintSet<ResolvedMediaTrackConstraint>;
23
24pub type SanitizedMediaTrackConstraintSet =
26 GenericMediaTrackConstraintSet<SanitizedMediaTrackConstraint>;
27
28#[derive(Debug, Clone, Eq, PartialEq)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40#[cfg_attr(feature = "serde", serde(transparent))]
41pub struct GenericMediaTrackConstraintSet<T>(IndexMap<MediaTrackProperty, T>);
42
43impl<T> GenericMediaTrackConstraintSet<T> {
44 pub fn new(constraint_set: IndexMap<MediaTrackProperty, T>) -> Self {
45 Self(constraint_set)
46 }
47
48 pub fn into_inner(self) -> IndexMap<MediaTrackProperty, T> {
49 self.0
50 }
51}
52
53impl<T> Deref for GenericMediaTrackConstraintSet<T> {
54 type Target = IndexMap<MediaTrackProperty, T>;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl<T> DerefMut for GenericMediaTrackConstraintSet<T> {
62 fn deref_mut(&mut self) -> &mut Self::Target {
63 &mut self.0
64 }
65}
66
67impl<T> Default for GenericMediaTrackConstraintSet<T> {
68 fn default() -> Self {
69 Self(IndexMap::new())
70 }
71}
72
73impl<T, U> FromIterator<(U, T)> for GenericMediaTrackConstraintSet<T>
74where
75 U: Into<MediaTrackProperty>,
76{
77 fn from_iter<I>(iter: I) -> Self
78 where
79 I: IntoIterator<Item = (U, T)>,
80 {
81 Self::new(iter.into_iter().map(|(k, v)| (k.into(), v)).collect())
82 }
83}
84
85impl<T> IntoIterator for GenericMediaTrackConstraintSet<T> {
86 type Item = (MediaTrackProperty, T);
87 type IntoIter = indexmap::map::IntoIter<MediaTrackProperty, T>;
88
89 fn into_iter(self) -> Self::IntoIter {
90 self.0.into_iter()
91 }
92}
93
94impl MediaTrackConstraintSet {
95 pub fn to_resolved(
96 &self,
97 strategy: MediaTrackConstraintResolutionStrategy,
98 ) -> ResolvedMediaTrackConstraintSet {
99 self.clone().into_resolved(strategy)
100 }
101
102 pub fn into_resolved(
103 self,
104 strategy: MediaTrackConstraintResolutionStrategy,
105 ) -> ResolvedMediaTrackConstraintSet {
106 ResolvedMediaTrackConstraintSet::new(
107 self.into_iter()
108 .map(|(property, constraint)| (property, constraint.into_resolved(strategy)))
109 .collect(),
110 )
111 }
112}
113
114impl ResolvedMediaTrackConstraintSet {
115 pub fn to_sanitized(
116 &self,
117 supported_constraints: &MediaTrackSupportedConstraints,
118 ) -> SanitizedMediaTrackConstraintSet {
119 self.clone().into_sanitized(supported_constraints)
120 }
121
122 pub fn into_sanitized(
123 self,
124 supported_constraints: &MediaTrackSupportedConstraints,
125 ) -> SanitizedMediaTrackConstraintSet {
126 let index_map: IndexMap<MediaTrackProperty, _> = self
127 .into_iter()
128 .filter_map(|(property, constraint)| {
129 if supported_constraints.contains(&property) {
130 constraint
131 .into_sanitized()
132 .map(|constraint| (property, constraint))
133 } else {
134 None
135 }
136 })
137 .collect();
138 SanitizedMediaTrackConstraintSet::new(index_map)
139 }
140}
141
142#[cfg(feature = "serde")]
143#[cfg(test)]
144mod serde_tests {
145 use crate::property::all::name::*;
146
147 use super::*;
148
149 #[test]
150 fn serialize_default() {
151 let constraint_set = MediaTrackConstraintSet::default();
152 let actual = serde_json::to_value(constraint_set).unwrap();
153 let expected = serde_json::json!({});
154
155 assert_eq!(actual, expected);
156 }
157
158 #[test]
159 fn deserialize_default() {
160 let json = serde_json::json!({});
161 let actual: MediaTrackConstraintSet = serde_json::from_value(json).unwrap();
162 let expected = MediaTrackConstraintSet::default();
163
164 assert_eq!(actual, expected);
165 }
166
167 #[test]
168 fn serialize() {
169 let constraint_set = MediaTrackConstraintSet::from_iter([
170 (&DEVICE_ID, "device-id".into()),
171 (&AUTO_GAIN_CONTROL, true.into()),
172 (&CHANNEL_COUNT, 2.into()),
173 (&LATENCY, 0.123.into()),
174 ]);
175 let actual = serde_json::to_value(constraint_set).unwrap();
176 let expected = serde_json::json!({
177 "deviceId": "device-id".to_owned(),
178 "autoGainControl": true,
179 "channelCount": 2,
180 "latency": 0.123,
181 });
182
183 assert_eq!(actual, expected);
184 }
185
186 #[test]
187 fn deserialize() {
188 let json = serde_json::json!({
189 "deviceId": "device-id".to_owned(),
190 "autoGainControl": true,
191 "channelCount": 2,
192 "latency": 0.123,
193 });
194 let actual: MediaTrackConstraintSet = serde_json::from_value(json).unwrap();
195 let expected = MediaTrackConstraintSet::from_iter([
196 (&DEVICE_ID, "device-id".into()),
197 (&AUTO_GAIN_CONTROL, true.into()),
198 (&CHANNEL_COUNT, 2.into()),
199 (&LATENCY, 0.123.into()),
200 ]);
201
202 assert_eq!(actual, expected);
203 }
204}