webrtc_constraints/capability/
value_range.rs1use std::ops::{RangeFrom, RangeInclusive, RangeToInclusive};
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Eq, PartialEq)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
26pub struct MediaTrackValueRangeCapability<T> {
27 #[cfg_attr(
28 feature = "serde",
29 serde(skip_serializing_if = "core::option::Option::is_none")
30 )]
31 pub min: Option<T>,
32 #[cfg_attr(
33 feature = "serde",
34 serde(skip_serializing_if = "core::option::Option::is_none")
35 )]
36 pub max: Option<T>,
37}
38
39impl<T> Default for MediaTrackValueRangeCapability<T> {
40 fn default() -> Self {
41 Self {
42 min: Default::default(),
43 max: Default::default(),
44 }
45 }
46}
47
48impl<T> From<RangeInclusive<T>> for MediaTrackValueRangeCapability<T> {
49 fn from(range: RangeInclusive<T>) -> Self {
50 let (min, max) = range.into_inner();
51 Self {
52 min: Some(min),
53 max: Some(max),
54 }
55 }
56}
57
58impl<T> From<RangeFrom<T>> for MediaTrackValueRangeCapability<T> {
59 fn from(range: RangeFrom<T>) -> Self {
60 Self {
61 min: Some(range.start),
62 max: None,
63 }
64 }
65}
66
67impl<T> From<RangeToInclusive<T>> for MediaTrackValueRangeCapability<T> {
68 fn from(range: RangeToInclusive<T>) -> Self {
69 Self {
70 min: None,
71 max: Some(range.end),
72 }
73 }
74}
75
76impl<T> MediaTrackValueRangeCapability<T> {
77 pub fn contains(&self, value: &T) -> bool
78 where
79 T: PartialOrd,
80 {
81 if let Some(ref min) = self.min {
84 if min > value {
85 return false;
86 }
87 }
88 if let Some(ref max) = self.max {
91 if max < value {
92 return false;
93 }
94 }
95 true
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 type Subject = MediaTrackValueRangeCapability<i64>;
104
105 #[test]
106 fn default() {
107 let subject = Subject::default();
108
109 assert_eq!(subject.min, None);
110 assert_eq!(subject.max, None);
111 }
112
113 mod from {
114 use super::*;
115
116 #[test]
117 fn range_inclusive() {
118 let subject = Subject::from(1..=5);
119
120 assert_eq!(subject.min, Some(1));
121 assert_eq!(subject.max, Some(5));
122 }
123
124 #[test]
125 fn range_from() {
126 let subject = Subject::from(1..);
127
128 assert_eq!(subject.min, Some(1));
129 assert_eq!(subject.max, None);
130 }
131
132 #[test]
133 fn range_to_inclusive() {
134 let subject = Subject::from(..=5);
135
136 assert_eq!(subject.min, None);
137 assert_eq!(subject.max, Some(5));
138 }
139 }
140
141 mod contains {
142 use super::*;
143
144 #[test]
145 fn default() {
146 let subject = Subject::default();
147
148 assert!(subject.contains(&0));
149 assert!(subject.contains(&1));
150 assert!(subject.contains(&5));
151 assert!(subject.contains(&6));
152 }
153
154 #[test]
155 fn from_range_inclusive() {
156 let subject = Subject::from(1..=5);
157
158 assert!(!subject.contains(&0));
159 assert!(subject.contains(&1));
160 assert!(subject.contains(&5));
161 assert!(!subject.contains(&6));
162 }
163
164 #[test]
165 fn from_range_from() {
166 let subject = Subject::from(1..);
167
168 assert!(!subject.contains(&0));
169 assert!(subject.contains(&1));
170 assert!(subject.contains(&5));
171 assert!(subject.contains(&6));
172 }
173
174 #[test]
175 fn from_range_to_inclusive() {
176 let subject = Subject::from(..=5);
177
178 assert!(subject.contains(&0));
179 assert!(subject.contains(&1));
180 assert!(subject.contains(&5));
181 assert!(!subject.contains(&6));
182 }
183 }
184}
185
186#[cfg(feature = "serde")]
187#[cfg(test)]
188mod serde_tests {
189 use crate::macros::test_serde_symmetry;
190
191 use super::*;
192
193 type Subject = MediaTrackValueRangeCapability<i64>;
194
195 #[test]
196 fn customized() {
197 let subject = Subject {
198 min: Some(12),
199 max: Some(34),
200 };
201 let json = serde_json::json!({
202 "min": 12,
203 "max": 34,
204 });
205
206 test_serde_symmetry!(subject: subject, json: json);
207 }
208}