xref: /webrtc/constraints/src/settings/track.rs (revision 6ac0fffd)
1 use std::{
2     collections::HashMap,
3     ops::{Deref, DerefMut},
4 };
5 
6 #[cfg(feature = "serde")]
7 use serde::{Deserialize, Serialize};
8 
9 use crate::MediaTrackSetting;
10 
11 /// The settings of a [`MediaStreamTrack`][media_stream_track] object.
12 ///
13 /// # W3C Spec Compliance
14 ///
15 /// Corresponds to [`MediaTrackSettings`][media_track_settings]
16 /// from the W3C ["Media Capture and Streams"][media_capture_and_streams_spec] spec.
17 ///
18 /// The W3C spec defines `MediaTrackSettings` in terma of a dictionary,
19 /// which per the [WebIDL spec][webidl_spec] is an ordered map (e.g. [`IndexMap<K, V>`][index_map]).
20 /// Since the spec however does not make use of the order of items
21 /// in the map we use a simple [`HashMap<K>`][hash_map].
22 ///
23 /// [hash_map]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
24 /// [index_map]: https://docs.rs/indexmap/latest/indexmap/set/struct.IndexMap.html
25 /// [media_stream_track]: https://www.w3.org/TR/mediacapture-streams/#dom-mediastreamtrack
26 /// [media_track_settings]: https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksettings
27 /// [media_capture_and_streams_spec]: https://www.w3.org/TR/mediacapture-streams
28 /// [webidl_spec]: https://webidl.spec.whatwg.org/#idl-dictionaries
29 #[derive(Debug, Clone, Default, PartialEq)]
30 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31 #[cfg_attr(feature = "serde", serde(transparent))]
32 pub struct MediaTrackSettings(HashMap<String, MediaTrackSetting>);
33 
34 impl MediaTrackSettings {
35     pub fn new(settings: HashMap<String, MediaTrackSetting>) -> Self {
36         Self(settings)
37     }
38 
39     pub fn into_inner(self) -> HashMap<String, MediaTrackSetting> {
40         self.0
41     }
42 }
43 
44 impl Deref for MediaTrackSettings {
45     type Target = HashMap<String, MediaTrackSetting>;
46 
47     fn deref(&self) -> &Self::Target {
48         &self.0
49     }
50 }
51 
52 impl DerefMut for MediaTrackSettings {
53     fn deref_mut(&mut self) -> &mut Self::Target {
54         &mut self.0
55     }
56 }
57 
58 impl<T> FromIterator<(T, MediaTrackSetting)> for MediaTrackSettings
59 where
60     T: Into<String>,
61 {
62     fn from_iter<I>(iter: I) -> Self
63     where
64         I: IntoIterator<Item = (T, MediaTrackSetting)>,
65     {
66         Self::new(iter.into_iter().map(|(k, v)| (k.into(), v)).collect())
67     }
68 }
69 
70 impl IntoIterator for MediaTrackSettings {
71     type Item = (String, MediaTrackSetting);
72     type IntoIter = std::collections::hash_map::IntoIter<String, MediaTrackSetting>;
73 
74     fn into_iter(self) -> Self::IntoIter {
75         self.0.into_iter()
76     }
77 }
78 
79 #[cfg(feature = "serde")]
80 #[cfg(test)]
81 mod serde_tests {
82     use crate::{macros::test_serde_symmetry, property::name::*};
83 
84     use super::*;
85 
86     type Subject = MediaTrackSettings;
87 
88     #[test]
89     fn default() {
90         let subject = Subject::default();
91         let json = serde_json::json!({});
92 
93         test_serde_symmetry!(subject: subject, json: json);
94     }
95 
96     #[test]
97     fn customized() {
98         let subject = Subject::from_iter([
99             (DEVICE_ID, "device-id".into()),
100             (AUTO_GAIN_CONTROL, true.into()),
101             (CHANNEL_COUNT, 2.into()),
102             (LATENCY, 0.123.into()),
103         ]);
104         let json = serde_json::json!({
105             "deviceId": "device-id".to_owned(),
106             "autoGainControl": true,
107             "channelCount": 2,
108             "latency": 0.123,
109         });
110 
111         test_serde_symmetry!(subject: subject, json: json);
112     }
113 }
114