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