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}