//! What a session reports, in device-neutral terms. Front ends print these, and `--json` //! serializes them as they are. use serde::{Serialize, Serializer}; /// Bumped whenever the JSON shape changes incompatibly. pub const JSON_SCHEMA: u32 = 1; #[derive(Debug, Default, Serialize)] pub struct Status { pub battery: Battery, pub noise_control: Option, /// Name of the current EQ preset. pub eq: Option, pub bass_level: Option, /// On/off settings, serialized as `{"game": false, …}`. #[serde(serialize_with = "switches_as_map")] pub switches: Vec, /// Audio codec of the link the buds report. pub codec: Option, pub firmware: Option, /// Reads that failed. The rest of the status is still valid. pub warnings: Vec, } #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize)] pub struct Battery { pub left: Option, pub right: Option, pub case: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] pub struct Charge { /// Percent. pub level: u8, pub charging: bool, } #[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct NoiseControl { /// `off`, `transparency` or `anc`, or `unknown (…)` for a value the device module cannot name. pub mode: String, /// The noise-cancelling level, when the device reports one. pub level: Option, } /// A noise-control mode to set. Levels come with W2. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum NoiseMode { Off, Transparency, Anc, } impl NoiseMode { /// The name [`NoiseControl::mode`] uses for it. pub fn name(self) -> &'static str { match self { NoiseMode::Off => "off", NoiseMode::Transparency => "transparency", NoiseMode::Anc => "anc", } } } #[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct Switch { /// Stable name used on the command line and in JSON (`game`, `dual`…). pub key: &'static str, /// Human name (`Game mode`). pub label: &'static str, pub on: bool, } #[derive(Debug, Default, Serialize)] pub struct TouchControls { pub gestures: Vec, /// Noise-control modes a hold steps through, when the device has that setting. pub hold_cycle: Option>, pub warnings: Vec, } #[derive(Debug, Clone, PartialEq, Eq, Serialize)] pub struct Gesture { /// `left`, `right` or `both`. pub side: String, /// `double-tap`, `triple-tap`, `hold`… pub gesture: String, /// `play-pause`, `next`, `none`… pub action: String, /// Raw button group, for entries outside the main gestures (calls). `None` for the main group. #[serde(skip_serializing_if = "Option::is_none")] pub group: Option, } fn switches_as_map(switches: &[Switch], serializer: S) -> Result { serializer.collect_map(switches.iter().map(|s| (s.key, s.on))) }