xref: /webrtc/constraints/src/capability.rs (revision 86143b07)
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     // IMPORTANT:
29     // `BoolSequence` must be ordered before `Bool(…)` in order for
30     // `serde` to decode the correct variant.
31     /// A sequence of boolean-valued media track capabilities.
32     BoolSequence(MediaTrackValueSequenceCapability<bool>),
33     /// A single boolean-valued media track capability.
34     Bool(MediaTrackValueCapability<bool>),
35     // `IntegerRange` must be ordered before `FloatRange(…)` in order for
36     // `serde` to decode the correct variant.
37     /// A range of integer-valued media track capabilities.
38     IntegerRange(MediaTrackValueRangeCapability<u64>),
39     /// A range of floating-point-valued media track capabilities.
40     FloatRange(MediaTrackValueRangeCapability<f64>),
41     // IMPORTANT:
42     // `StringSequence` must be ordered before `String(…)` in order for
43     // `serde` to decode the correct variant.
44     /// A sequence of string-valued media track capabilities.
45     StringSequence(MediaTrackValueSequenceCapability<String>),
46     /// A single string-valued media track capability.
47     String(MediaTrackValueCapability<String>),
48 }
49 
50 impl From<bool> for MediaTrackCapability {
from(capability: bool) -> Self51     fn from(capability: bool) -> Self {
52         Self::Bool(capability.into())
53     }
54 }
55 
56 impl From<Vec<bool>> for MediaTrackCapability {
from(capability: Vec<bool>) -> Self57     fn from(capability: Vec<bool>) -> Self {
58         Self::BoolSequence(capability.into())
59     }
60 }
61 
62 impl From<RangeInclusive<u64>> for MediaTrackCapability {
from(capability: RangeInclusive<u64>) -> Self63     fn from(capability: RangeInclusive<u64>) -> Self {
64         Self::IntegerRange(capability.into())
65     }
66 }
67 
68 impl From<RangeInclusive<f64>> for MediaTrackCapability {
from(capability: RangeInclusive<f64>) -> Self69     fn from(capability: RangeInclusive<f64>) -> Self {
70         Self::FloatRange(capability.into())
71     }
72 }
73 
74 impl From<String> for MediaTrackCapability {
from(capability: String) -> Self75     fn from(capability: String) -> Self {
76         Self::String(capability.into())
77     }
78 }
79 
80 impl<'a> From<&'a str> for MediaTrackCapability {
from(capability: &'a str) -> Self81     fn from(capability: &'a str) -> Self {
82         let capability: String = capability.to_owned();
83         Self::from(capability)
84     }
85 }
86 
87 impl From<Vec<String>> for MediaTrackCapability {
from(capability: Vec<String>) -> Self88     fn from(capability: Vec<String>) -> Self {
89         Self::StringSequence(capability.into())
90     }
91 }
92 
93 impl From<Vec<&str>> for MediaTrackCapability {
from(capability: Vec<&str>) -> Self94     fn from(capability: Vec<&str>) -> Self {
95         let capability: Vec<String> = capability.into_iter().map(|c| c.to_owned()).collect();
96         Self::from(capability)
97     }
98 }
99 
100 #[cfg(test)]
101 mod tests {
102     use super::*;
103 
104     type Subject = MediaTrackCapability;
105 
106     mod from {
107         use super::*;
108 
109         #[test]
bool_sequence()110         fn bool_sequence() {
111             let actual = Subject::from(vec![false, true]);
112             let expected = Subject::BoolSequence(vec![false, true].into());
113 
114             assert_eq!(actual, expected);
115         }
116 
117         #[test]
bool()118         fn bool() {
119             let actual = Subject::from(true);
120             let expected = Subject::Bool(true.into());
121 
122             assert_eq!(actual, expected);
123         }
124 
125         #[test]
integer_range()126         fn integer_range() {
127             let actual = Subject::from(12..=34);
128             let expected = Subject::IntegerRange((12..=34).into());
129 
130             assert_eq!(actual, expected);
131         }
132 
133         #[test]
float()134         fn float() {
135             let actual = Subject::from(1.2..=3.4);
136             let expected = Subject::FloatRange((1.2..=3.4).into());
137 
138             assert_eq!(actual, expected);
139         }
140 
141         #[test]
string_sequence()142         fn string_sequence() {
143             let actual = Subject::from(vec!["foo".to_owned(), "bar".to_owned()]);
144             let expected = Subject::StringSequence(vec!["foo".to_owned(), "bar".to_owned()].into());
145 
146             assert_eq!(actual, expected);
147         }
148 
149         #[test]
string()150         fn string() {
151             let actual = Subject::from("foo".to_owned());
152             let expected = Subject::String("foo".to_owned().into());
153 
154             assert_eq!(actual, expected);
155         }
156     }
157 }
158 
159 #[cfg(feature = "serde")]
160 #[cfg(test)]
161 mod serde_tests {
162     use crate::macros::test_serde_symmetry;
163 
164     use super::*;
165 
166     type Subject = MediaTrackCapability;
167 
168     #[test]
bool_sequence()169     fn bool_sequence() {
170         let subject = Subject::BoolSequence(vec![false, true].into());
171         let json = serde_json::json!([false, true]);
172 
173         test_serde_symmetry!(subject: subject, json: json);
174     }
175 
176     #[test]
bool()177     fn bool() {
178         let subject = Subject::Bool(true.into());
179         let json = serde_json::json!(true);
180 
181         test_serde_symmetry!(subject: subject, json: json);
182     }
183 
184     #[test]
integer_range()185     fn integer_range() {
186         let subject = Subject::IntegerRange((12..=34).into());
187         let json = serde_json::json!({
188             "min": 12,
189             "max": 34,
190         });
191 
192         test_serde_symmetry!(subject: subject, json: json);
193     }
194 
195     #[test]
float()196     fn float() {
197         let subject = Subject::FloatRange((1.2..=3.4).into());
198         let json = serde_json::json!({
199             "min": 1.2,
200             "max": 3.4,
201         });
202 
203         test_serde_symmetry!(subject: subject, json: json);
204     }
205 
206     #[test]
string_sequence()207     fn string_sequence() {
208         let subject = Subject::StringSequence(vec!["foo".to_owned(), "bar".to_owned()].into());
209         let json = serde_json::json!(["foo", "bar"]);
210 
211         test_serde_symmetry!(subject: subject, json: json);
212     }
213 
214     #[test]
string()215     fn string() {
216         let subject = Subject::String("foo".to_owned().into());
217         let json = serde_json::json!("foo");
218 
219         test_serde_symmetry!(subject: subject, json: json);
220     }
221 }
222