xref: /webrtc/constraints/src/capability.rs (revision 8b68b472)
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(feature = "serde")]
93 #[cfg(test)]
94 mod serde_tests {
95     use crate::macros::test_serde_symmetry;
96 
97     use super::*;
98 
99     type Subject = MediaTrackCapability;
100 
101     #[test]
102     fn bool_sequence() {
103         let subject = Subject::BoolSequence(vec![false, true].into());
104         let json = serde_json::json!([false, true]);
105 
106         test_serde_symmetry!(subject: subject, json: json);
107     }
108 
109     #[test]
110     fn bool() {
111         let subject = Subject::Bool(true.into());
112         let json = serde_json::json!(true);
113 
114         test_serde_symmetry!(subject: subject, json: json);
115     }
116 
117     #[test]
118     fn integer_range() {
119         let subject = Subject::IntegerRange((12..=34).into());
120         let json = serde_json::json!({
121             "min": 12,
122             "max": 34,
123         });
124 
125         test_serde_symmetry!(subject: subject, json: json);
126     }
127 
128     #[test]
129     fn float() {
130         let subject = Subject::FloatRange((1.2..=3.4).into());
131         let json = serde_json::json!({
132             "min": 1.2,
133             "max": 3.4,
134         });
135 
136         test_serde_symmetry!(subject: subject, json: json);
137     }
138 
139     #[test]
140     fn string_sequence() {
141         let subject = Subject::StringSequence(vec!["foo".to_owned(), "bar".to_owned()].into());
142         let json = serde_json::json!(["foo", "bar"]);
143 
144         test_serde_symmetry!(subject: subject, json: json);
145     }
146 
147     #[test]
148     fn string() {
149         let subject = Subject::String("foo".to_owned().into());
150         let json = serde_json::json!("foo");
151 
152         test_serde_symmetry!(subject: subject, json: json);
153     }
154 }
155