xref: /webrtc/constraints/src/capability.rs (revision 1f428f4d)
1 mod value;
2 mod value_range;
3 mod value_sequence;
4 
5 use std::ops::RangeInclusive;
6 
7 #[cfg(feature = "serde")]
8 use serde::{Deserialize, Serialize};
9 
10 pub use self::{
11     value::MediaTrackValueCapability, value_range::MediaTrackValueRangeCapability,
12     value_sequence::MediaTrackValueSequenceCapability,
13 };
14 
15 /// A single [capability][media_track_capabilities] value of a [`MediaStreamTrack`][media_stream_track] object.
16 ///
17 /// # W3C Spec Compliance
18 ///
19 /// There exists no corresponding type in the W3C ["Media Capture and Streams"][media_capture_and_streams_spec] spec.
20 ///
21 /// [media_stream_track]: https://www.w3.org/TR/mediacapture-streams/#dom-mediastreamtrack
22 /// [media_track_capabilities]: https://www.w3.org/TR/mediacapture-streams/#dom-mediatrackcapabilities
23 /// [media_capture_and_streams_spec]: https://www.w3.org/TR/mediacapture-streams
24 #[derive(Debug, Clone, PartialEq)]
25 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26 #[cfg_attr(feature = "serde", serde(untagged))]
27 pub enum MediaTrackCapability {
28     // `BoolSequence` must be ordered before `Bool(…)` in order for
29     // `serde` to decode the correct variant.
30     BoolSequence(MediaTrackValueSequenceCapability<bool>),
31     Bool(MediaTrackValueCapability<bool>),
32     // `IntegerRange` must be ordered before `FloatRange(…)` in order for
33     // `serde` to decode the correct variant.
34     IntegerRange(MediaTrackValueRangeCapability<u64>),
35     FloatRange(MediaTrackValueRangeCapability<f64>),
36     // `StringSequence` must be ordered before `String(…)` in order for
37     // `serde` to decode the correct variant.
38     StringSequence(MediaTrackValueSequenceCapability<String>),
39     String(MediaTrackValueCapability<String>),
40 }
41 
42 impl From<bool> for MediaTrackCapability {
43     fn from(capability: bool) -> Self {
44         Self::Bool(capability.into())
45     }
46 }
47 
48 impl From<Vec<bool>> for MediaTrackCapability {
49     fn from(capability: Vec<bool>) -> Self {
50         Self::BoolSequence(capability.into())
51     }
52 }
53 
54 impl From<RangeInclusive<u64>> for MediaTrackCapability {
55     fn from(capability: RangeInclusive<u64>) -> Self {
56         Self::IntegerRange(capability.into())
57     }
58 }
59 
60 impl From<RangeInclusive<f64>> for MediaTrackCapability {
61     fn from(capability: RangeInclusive<f64>) -> Self {
62         Self::FloatRange(capability.into())
63     }
64 }
65 
66 impl From<String> for MediaTrackCapability {
67     fn from(capability: String) -> Self {
68         Self::String(capability.into())
69     }
70 }
71 
72 impl<'a> From<&'a str> for MediaTrackCapability {
73     fn from(capability: &'a str) -> Self {
74         let capability: String = capability.to_owned();
75         Self::from(capability)
76     }
77 }
78 
79 impl From<Vec<String>> for MediaTrackCapability {
80     fn from(capability: Vec<String>) -> Self {
81         Self::StringSequence(capability.into())
82     }
83 }
84 
85 impl From<Vec<&str>> for MediaTrackCapability {
86     fn from(capability: Vec<&str>) -> Self {
87         let capability: Vec<String> = capability.into_iter().map(|c| c.to_owned()).collect();
88         Self::from(capability)
89     }
90 }
91 
92 #[cfg(test)]
93 mod tests {
94     use super::*;
95 
96     type Subject = MediaTrackCapability;
97 
98     mod from {
99         use super::*;
100 
101         #[test]
102         fn bool_sequence() {
103             let actual = Subject::from(vec![false, true]);
104             let expected = Subject::BoolSequence(vec![false, true].into());
105 
106             assert_eq!(actual, expected);
107         }
108 
109         #[test]
110         fn bool() {
111             let actual = Subject::from(true);
112             let expected = Subject::Bool(true.into());
113 
114             assert_eq!(actual, expected);
115         }
116 
117         #[test]
118         fn integer_range() {
119             let actual = Subject::from(12..=34);
120             let expected = Subject::IntegerRange((12..=34).into());
121 
122             assert_eq!(actual, expected);
123         }
124 
125         #[test]
126         fn float() {
127             let actual = Subject::from(1.2..=3.4);
128             let expected = Subject::FloatRange((1.2..=3.4).into());
129 
130             assert_eq!(actual, expected);
131         }
132 
133         #[test]
134         fn string_sequence() {
135             let actual = Subject::from(vec!["foo".to_owned(), "bar".to_owned()]);
136             let expected = Subject::StringSequence(vec!["foo".to_owned(), "bar".to_owned()].into());
137 
138             assert_eq!(actual, expected);
139         }
140 
141         #[test]
142         fn string() {
143             let actual = Subject::from("foo".to_owned());
144             let expected = Subject::String("foo".to_owned().into());
145 
146             assert_eq!(actual, expected);
147         }
148     }
149 }
150 
151 #[cfg(feature = "serde")]
152 #[cfg(test)]
153 mod serde_tests {
154     use crate::macros::test_serde_symmetry;
155 
156     use super::*;
157 
158     type Subject = MediaTrackCapability;
159 
160     #[test]
161     fn bool_sequence() {
162         let subject = Subject::BoolSequence(vec![false, true].into());
163         let json = serde_json::json!([false, true]);
164 
165         test_serde_symmetry!(subject: subject, json: json);
166     }
167 
168     #[test]
169     fn bool() {
170         let subject = Subject::Bool(true.into());
171         let json = serde_json::json!(true);
172 
173         test_serde_symmetry!(subject: subject, json: json);
174     }
175 
176     #[test]
177     fn integer_range() {
178         let subject = Subject::IntegerRange((12..=34).into());
179         let json = serde_json::json!({
180             "min": 12,
181             "max": 34,
182         });
183 
184         test_serde_symmetry!(subject: subject, json: json);
185     }
186 
187     #[test]
188     fn float() {
189         let subject = Subject::FloatRange((1.2..=3.4).into());
190         let json = serde_json::json!({
191             "min": 1.2,
192             "max": 3.4,
193         });
194 
195         test_serde_symmetry!(subject: subject, json: json);
196     }
197 
198     #[test]
199     fn string_sequence() {
200         let subject = Subject::StringSequence(vec!["foo".to_owned(), "bar".to_owned()].into());
201         let json = serde_json::json!(["foo", "bar"]);
202 
203         test_serde_symmetry!(subject: subject, json: json);
204     }
205 
206     #[test]
207     fn string() {
208         let subject = Subject::String("foo".to_owned().into());
209         let json = serde_json::json!("foo");
210 
211         test_serde_symmetry!(subject: subject, json: json);
212     }
213 }
214