use std::{ collections::HashMap, ops::{Deref, DerefMut}, }; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use crate::MediaTrackSetting; /// The settings of a [`MediaStreamTrack`][media_stream_track] object. /// /// # W3C Spec Compliance /// /// Corresponds to [`MediaTrackSettings`][media_track_settings] /// from the W3C ["Media Capture and Streams"][media_capture_and_streams_spec] spec. /// /// The W3C spec defines `MediaTrackSettings` in terma of a dictionary, /// which per the [WebIDL spec][webidl_spec] is an ordered map (e.g. [`IndexMap`][index_map]). /// Since the spec however does not make use of the order of items /// in the map we use a simple [`HashMap`][hash_map]. /// /// [hash_map]: https://doc.rust-lang.org/std/collections/struct.HashMap.html /// [index_map]: https://docs.rs/indexmap/latest/indexmap/set/struct.IndexMap.html /// [media_stream_track]: https://www.w3.org/TR/mediacapture-streams/#dom-mediastreamtrack /// [media_track_settings]: https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksettings /// [media_capture_and_streams_spec]: https://www.w3.org/TR/mediacapture-streams /// [webidl_spec]: https://webidl.spec.whatwg.org/#idl-dictionaries #[derive(Debug, Clone, Default, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(transparent))] pub struct MediaTrackSettings(HashMap); impl MediaTrackSettings { pub fn new(settings: HashMap) -> Self { Self(settings) } pub fn into_inner(self) -> HashMap { self.0 } } impl Deref for MediaTrackSettings { type Target = HashMap; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for MediaTrackSettings { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl FromIterator<(T, MediaTrackSetting)> for MediaTrackSettings where T: Into, { fn from_iter(iter: I) -> Self where I: IntoIterator, { Self::new(iter.into_iter().map(|(k, v)| (k.into(), v)).collect()) } } impl IntoIterator for MediaTrackSettings { type Item = (String, MediaTrackSetting); type IntoIter = std::collections::hash_map::IntoIter; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } #[cfg(feature = "serde")] #[cfg(test)] mod serde_tests { use crate::{macros::test_serde_symmetry, property::name::*}; use super::*; type Subject = MediaTrackSettings; #[test] fn default() { let subject = Subject::default(); let json = serde_json::json!({}); test_serde_symmetry!(subject: subject, json: json); } #[test] fn customized() { let subject = Subject::from_iter([ (DEVICE_ID, "device-id".into()), (AUTO_GAIN_CONTROL, true.into()), (CHANNEL_COUNT, 2.into()), (LATENCY, 0.123.into()), ]); let json = serde_json::json!({ "deviceId": "device-id".to_owned(), "autoGainControl": true, "channelCount": 2, "latency": 0.123, }); test_serde_symmetry!(subject: subject, json: json); } }