1 #[cfg(feature = "serde")] 2 use serde::{Deserialize, Serialize}; 3 4 /// A bare value or constraint specifying a sequence of accepted values. 5 /// 6 /// # W3C Spec Compliance 7 /// 8 /// There exists no direct corresponding type in the 9 /// W3C ["Media Capture and Streams"][media_capture_and_streams_spec] spec, 10 /// since the `BareOrValueConstraint<T>` type aims to be a generalization over 11 /// multiple types in the spec. 12 /// 13 /// | Rust | W3C | 14 /// | ---------------------------------------- | -------------------------------------------- | 15 /// | `BareOrValueSequenceConstraint<String>` | [`ConstrainDOMString`][constrain_dom_string] | 16 /// 17 /// [constrain_dom_string]: https://www.w3.org/TR/mediacapture-streams/#dom-constraindomstring 18 /// [media_capture_and_streams_spec]: https://www.w3.org/TR/mediacapture-streams/ 19 #[derive(Debug, Clone, PartialEq)] 20 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 21 #[cfg_attr(feature = "serde", serde(untagged))] 22 pub enum BareOrValueSequenceConstraint<T> { 23 Bare(Vec<T>), 24 Constraint(ValueSequenceConstraint<T>), 25 } 26 27 impl<T> Default for BareOrValueSequenceConstraint<T> { 28 fn default() -> Self { 29 Self::Constraint(Default::default()) 30 } 31 } 32 33 impl<T> From<T> for BareOrValueSequenceConstraint<T> { 34 fn from(bare: T) -> Self { 35 Self::Bare(vec![bare]) 36 } 37 } 38 39 impl<T> From<Vec<T>> for BareOrValueSequenceConstraint<T> { 40 fn from(bare: Vec<T>) -> Self { 41 Self::Bare(bare) 42 } 43 } 44 45 impl<T> From<ValueSequenceConstraint<T>> for BareOrValueSequenceConstraint<T> { 46 fn from(constraint: ValueSequenceConstraint<T>) -> Self { 47 Self::Constraint(constraint) 48 } 49 } 50 51 /// A constraint specifying a sequence of accepted values. 52 /// 53 /// # W3C Spec Compliance 54 /// 55 /// There exists no direct corresponding type in the 56 /// W3C ["Media Capture and Streams"][media_capture_and_streams_spec] spec, 57 /// since the `BareOrValueSequenceConstraint<T>` type aims to be a 58 /// generalization over multiple types in the W3C spec: 59 /// 60 /// | Rust | W3C | 61 /// | --------------------------------- | ----------------------------------------------------------------- | 62 /// | `ValueSequenceConstraint<String>` | [`ConstrainDOMStringParameters`][constrain_dom_string_parameters] | 63 /// 64 /// [constrain_dom_string_parameters]: https://www.w3.org/TR/mediacapture-streams/#dom-constraindomstringparameters 65 /// [media_capture_and_streams_spec]: https://www.w3.org/TR/mediacapture-streams/ 66 #[derive(Debug, Clone, PartialEq)] 67 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 68 #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] 69 pub struct ValueSequenceConstraint<T> { 70 // See https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#constraindomstring 71 #[cfg_attr( 72 feature = "serde", 73 serde(skip_serializing_if = "core::option::Option::is_none") 74 )] 75 pub exact: Option<Vec<T>>, 76 #[cfg_attr( 77 feature = "serde", 78 serde(skip_serializing_if = "core::option::Option::is_none") 79 )] 80 pub ideal: Option<Vec<T>>, 81 } 82 83 impl<T> ValueSequenceConstraint<T> { 84 pub fn exact_only(exact: Vec<T>) -> Self { 85 Self { 86 exact: Some(exact), 87 ideal: None, 88 } 89 } 90 91 pub fn ideal_only(ideal: Vec<T>) -> Self { 92 Self { 93 exact: None, 94 ideal: Some(ideal), 95 } 96 } 97 98 pub fn is_required(&self) -> bool { 99 self.exact.is_some() 100 } 101 } 102 103 impl<T> Default for ValueSequenceConstraint<T> { 104 fn default() -> Self { 105 Self { 106 exact: None, 107 ideal: None, 108 } 109 } 110 } 111 112 #[cfg(feature = "serde")] 113 #[cfg(test)] 114 mod serde_tests { 115 use crate::macros::test_serde_symmetry; 116 117 use super::*; 118 119 macro_rules! test_serde { 120 ($t:ty => { 121 values: [$($values:expr),*] 122 }) => { 123 type Subject = BareOrValueSequenceConstraint<$t>; 124 125 #[test] 126 fn default() { 127 let subject = Subject::default(); 128 let json = serde_json::json!({}); 129 130 test_serde_symmetry!(subject: subject, json: json); 131 } 132 133 #[test] 134 fn bare() { 135 let subject = Subject::Bare(vec![$($values.to_owned()),*].into()); 136 let json = serde_json::json!([$($values),*]); 137 138 test_serde_symmetry!(subject: subject, json: json); 139 } 140 141 #[test] 142 fn constraint() { 143 let subject = Subject::Constraint(ValueSequenceConstraint::<String> { 144 exact: Some(vec![$($values.to_owned()),*].into()), 145 ideal: None, 146 }); 147 let json = serde_json::json!({ 148 "exact": [$($values),*], 149 }); 150 151 test_serde_symmetry!(subject: subject, json: json); 152 } 153 }; 154 } 155 156 mod string { 157 use super::*; 158 159 test_serde!(String => { 160 values: ["VALUE_0", "VALUE_1"] 161 }); 162 } 163 } 164