webrtc_constraints/property.rs
1//! Constants identifying the properties of a [`MediaStreamTrack`][media_stream_track] object,
2//! as defined in the ["Media Capture and Streams"][media_track_supported_constraints] spec.
3//!
4//! [media_stream_track]: https://www.w3.org/TR/mediacapture-streams/#mediastreamtrack
5//! [media_track_supported_constraints]: https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksupportedconstraints
6
7use std::{borrow::Cow, fmt::Display};
8
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12/// An identifier for a media track property.
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14#[cfg_attr(feature = "serde", serde(transparent))]
15#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
16pub struct MediaTrackProperty(Cow<'static, str>);
17
18impl From<&MediaTrackProperty> for MediaTrackProperty {
19 fn from(borrowed: &MediaTrackProperty) -> Self {
20 borrowed.clone()
21 }
22}
23
24impl From<String> for MediaTrackProperty {
25 /// Creates a property from an owned representation of its name.
26 fn from(owned: String) -> Self {
27 Self(Cow::Owned(owned))
28 }
29}
30
31impl From<&str> for MediaTrackProperty {
32 /// Creates a property from an owned representation of its name.
33 ///
34 /// Use `MediaTrackProperty::named(str)` if your property name
35 /// is statically borrowed (i.e. `&'static str`).
36 fn from(borrowed: &str) -> Self {
37 Self(Cow::Owned(borrowed.to_owned()))
38 }
39}
40
41impl Display for MediaTrackProperty {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 f.write_str(&self.0)
44 }
45}
46
47impl MediaTrackProperty {
48 /// Creates a property from a statically borrowed representation of its name.
49 pub const fn named(name: &'static str) -> Self {
50 Self(Cow::Borrowed(name))
51 }
52
53 /// The property's name.
54 pub fn name(&self) -> &str {
55 &self.0
56 }
57}
58
59/// Standard properties that apply to both, audio and video device types.
60pub mod common {
61 use super::*;
62
63 /// Names of common properties.
64 pub mod name {
65 use super::*;
66
67 /// The identifier of the device generating the content of the track,
68 /// as defined in the [spec][spec].
69 ///
70 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-deviceid
71 pub static DEVICE_ID: MediaTrackProperty = MediaTrackProperty::named("deviceId");
72
73 /// The document-unique group identifier for the device generating the content
74 /// of the track, as defined in the [spec][spec].
75 ///
76 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-groupid
77 pub static GROUP_ID: MediaTrackProperty = MediaTrackProperty::named("groupId");
78 }
79
80 /// Names of common properties.
81 pub fn names() -> Vec<&'static MediaTrackProperty> {
82 use self::name::*;
83
84 vec![&DEVICE_ID, &GROUP_ID]
85 }
86}
87
88/// Standard properties that apply only to audio device types.
89pub mod audio_only {
90 use super::*;
91
92 /// Names of audio-only properties.
93 pub mod name {
94 use super::*;
95
96 /// Automatic gain control is often desirable on the input signal recorded
97 /// by the microphone, as defined in the [spec][spec].
98 ///
99 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-autogaincontrol
100 pub static AUTO_GAIN_CONTROL: MediaTrackProperty =
101 MediaTrackProperty::named("autoGainControl");
102
103 /// The number of independent channels of sound that the audio data contains,
104 /// i.e. the number of audio samples per sample frame, as defined in the [spec][spec].
105 ///
106 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-channelcount
107 pub static CHANNEL_COUNT: MediaTrackProperty = MediaTrackProperty::named("channelCount");
108
109 /// When one or more audio streams is being played in the processes of
110 /// various microphones, it is often desirable to attempt to remove
111 /// all the sound being played from the input signals recorded by the microphones.
112 /// This is referred to as echo cancellation, as defined in the [spec][spec].
113 ///
114 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-echocancellation
115 pub static ECHO_CANCELLATION: MediaTrackProperty =
116 MediaTrackProperty::named("echoCancellation");
117
118 /// The latency or latency range, in seconds, as defined in the [spec][spec].
119 ///
120 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-latency
121 pub static LATENCY: MediaTrackProperty = MediaTrackProperty::named("latency");
122
123 /// Noise suppression is often desirable on the input signal recorded by the microphone,
124 /// as defined in the [spec][spec].
125 ///
126 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-noisesuppression
127 pub static NOISE_SUPPRESSION: MediaTrackProperty =
128 MediaTrackProperty::named("noiseSuppression");
129
130 /// The sample rate in samples per second for the audio data, as defined in the [spec][spec].
131 ///
132 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-samplerate
133 pub static SAMPLE_RATE: MediaTrackProperty = MediaTrackProperty::named("sampleRate");
134
135 /// The linear sample size in bits. This constraint can only
136 /// be satisfied for audio devices that produce linear samples, as defined in the [spec][spec].
137 ///
138 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-samplesize
139 pub static SAMPLE_SIZE: MediaTrackProperty = MediaTrackProperty::named("sampleSize");
140 }
141
142 /// Names of all audio-only properties.
143 pub fn names() -> Vec<&'static MediaTrackProperty> {
144 use self::name::*;
145
146 vec![
147 &AUTO_GAIN_CONTROL,
148 &CHANNEL_COUNT,
149 &ECHO_CANCELLATION,
150 &LATENCY,
151 &NOISE_SUPPRESSION,
152 &SAMPLE_RATE,
153 &SAMPLE_SIZE,
154 ]
155 }
156}
157
158/// Standard properties that apply only to video device types.
159pub mod video_only {
160 use super::*;
161
162 /// Names of audio-only properties.
163 pub mod name {
164 use super::*;
165
166 /// The exact aspect ratio (width in pixels divided by height in pixels,
167 /// represented as a double rounded to the tenth decimal place),
168 /// as defined in the [spec][spec].
169 ///
170 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-aspectratio
171 pub static ASPECT_RATIO: MediaTrackProperty = MediaTrackProperty::named("aspectRatio");
172
173 /// The directions that the camera can face, as seen from the user's perspective,
174 /// as defined in the [spec][spec].
175 ///
176 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-facingmode
177 pub static FACING_MODE: MediaTrackProperty = MediaTrackProperty::named("facingMode");
178
179 /// The exact frame rate (frames per second) or frame rate range,
180 /// as defined in the [spec][spec].
181 ///
182 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-framerate
183 pub static FRAME_RATE: MediaTrackProperty = MediaTrackProperty::named("frameRate");
184
185 /// The height or height range, in pixels, as defined in the [spec][spec].
186 ///
187 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-height
188 pub static HEIGHT: MediaTrackProperty = MediaTrackProperty::named("height");
189
190 /// The width or width range, in pixels, as defined in the [spec][spec].
191 ///
192 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-width
193 pub static WIDTH: MediaTrackProperty = MediaTrackProperty::named("width");
194
195 /// The means by which the resolution can be derived by the client, as defined in the [spec][spec].
196 ///
197 /// In other words, whether the client is allowed to use cropping and downscaling on the camera output.
198 ///
199 /// [spec]: https://www.w3.org/TR/mediacapture-streams/#dfn-resizemode
200 pub static RESIZE_MODE: MediaTrackProperty = MediaTrackProperty::named("resizeMode");
201 }
202
203 /// Names of all video-only properties.
204 pub fn names() -> Vec<&'static MediaTrackProperty> {
205 use self::name::*;
206 vec![
207 &ASPECT_RATIO,
208 &FACING_MODE,
209 &FRAME_RATE,
210 &HEIGHT,
211 &WIDTH,
212 &RESIZE_MODE,
213 ]
214 }
215}
216
217/// The union of all standard properties (i.e. common + audio + video).
218pub mod all {
219 use super::*;
220
221 /// Names of all properties.
222 pub mod name {
223 pub use super::audio_only::name::*;
224 pub use super::common::name::*;
225 pub use super::video_only::name::*;
226 }
227
228 /// Names of all properties.
229 pub fn names() -> Vec<&'static MediaTrackProperty> {
230 let mut all = vec![];
231 all.append(&mut self::common::names());
232 all.append(&mut self::audio_only::names());
233 all.append(&mut self::video_only::names());
234 all
235 }
236}
237
238#[cfg(test)]
239mod tests {
240 use super::*;
241
242 type Subject = MediaTrackProperty;
243
244 mod from {
245 use super::*;
246
247 #[test]
248 fn owned() {
249 let actuals = [Subject::from("string"), Subject::from("string".to_owned())];
250 let expected = MediaTrackProperty(Cow::Owned("string".to_owned()));
251
252 for actual in actuals {
253 assert_eq!(actual, expected);
254
255 // TODO: remove feature-gate, once stabilized:
256 #[cfg(feature = "cow_is_borrowed")]
257 assert!(actual.0.is_owned());
258 }
259 }
260
261 #[test]
262 fn borrowed() {
263 let actual = Subject::named("string");
264 let expected = MediaTrackProperty(Cow::Borrowed("string"));
265
266 assert_eq!(actual, expected);
267
268 // TODO: remove feature-gate, once stabilized:
269 #[cfg(feature = "cow_is_borrowed")]
270 assert!(actual.0.is_borrowed());
271 }
272 }
273
274 #[test]
275 fn name() {
276 assert_eq!(Subject::named("string").name(), "string");
277 }
278
279 #[test]
280 fn to_string() {
281 assert_eq!(Subject::named("string").to_string(), "string");
282 }
283}
284
285#[cfg(feature = "serde")]
286#[cfg(test)]
287mod serde_tests {
288 use crate::macros::test_serde_symmetry;
289
290 use super::*;
291
292 type Subject = MediaTrackProperty;
293
294 #[test]
295 fn is_symmetric() {
296 let subject = Subject::named("string");
297 let json = serde_json::json!("string");
298
299 test_serde_symmetry!(subject: subject, json: json);
300 }
301}