Use PropertyDescriptorWrapper for json output
This commit is contained in:
@@ -234,37 +234,52 @@ fn main() {
|
||||
let properties = &device.get_device_state().device_properties;
|
||||
let mut headset_info_string = "{\n".to_string();
|
||||
|
||||
macro_rules! append_json_property {
|
||||
($val:expr, $name:ident) => {
|
||||
if let Some($name) = $val {
|
||||
headset_info_string +=
|
||||
&format!(" \"{}\": \"{}\",\n", stringify!($name), $name);
|
||||
}
|
||||
};
|
||||
let mut json_properties: Vec<String> = properties
|
||||
.get_properties()
|
||||
.iter()
|
||||
.map(|property| match property {
|
||||
hyper_headset::devices::PropertyDescriptorWrapper::Int(
|
||||
property_descriptor,
|
||||
_items,
|
||||
) => match property_descriptor.data {
|
||||
Some(data) => format!(" \"{}\": {},\n", property_descriptor.name, data),
|
||||
_ => "".to_string(),
|
||||
},
|
||||
hyper_headset::devices::PropertyDescriptorWrapper::Bool(
|
||||
property_descriptor,
|
||||
) => match property_descriptor.data {
|
||||
Some(data) => format!(" \"{}\": {},\n", property_descriptor.name, data),
|
||||
_ => "".to_string(),
|
||||
},
|
||||
hyper_headset::devices::PropertyDescriptorWrapper::String(
|
||||
property_descriptor,
|
||||
) => match &property_descriptor.data {
|
||||
Some(data) => {
|
||||
format!(" \"{}\": \"{}\",\n", property_descriptor.name, data)
|
||||
}
|
||||
_ => "".to_string(),
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
|
||||
// The last property needs to end without a comma
|
||||
match json_properties.last_mut() {
|
||||
#[allow(unused_assignments)]
|
||||
Some(mut json_property) => {
|
||||
let mut last_property = json_property[0..(json_property.len() - 2)].to_string();
|
||||
last_property += "\n";
|
||||
json_property = &mut last_property;
|
||||
}
|
||||
None => {
|
||||
// Unreachable:
|
||||
// The program exits if no device is found
|
||||
// but also has a property for the device being connected
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
append_json_property!(&properties.device_name, device_name);
|
||||
append_json_property!(properties.battery_level, battery_level);
|
||||
append_json_property!(properties.charging, charging);
|
||||
append_json_property!(properties.muted, muted);
|
||||
append_json_property!(properties.mic_connected, mic_connected);
|
||||
append_json_property!(properties.pairing_info, pairing_info);
|
||||
append_json_property!(properties.product_color, product_color);
|
||||
append_json_property!(properties.side_tone_on, side_tone_on);
|
||||
append_json_property!(properties.side_tone_volume, side_tone_volume);
|
||||
append_json_property!(properties.surround_sound, surround_sound);
|
||||
append_json_property!(properties.voice_prompt_on, voice_prompt_on);
|
||||
append_json_property!(properties.connected, connected);
|
||||
append_json_property!(properties.silent, silent);
|
||||
append_json_property!(properties.noise_gate_active, noise_gate_active);
|
||||
|
||||
// This is the last property so it shouldn't have a comma at the end
|
||||
// Durations also do not implement `Display` so this needs to be output manually
|
||||
if let Some(automatic_shutdown_interval) = properties.automatic_shutdown_after {
|
||||
headset_info_string += &format!(
|
||||
" \"automatic_shutdown_interval\": \"{}\"\n",
|
||||
automatic_shutdown_interval.as_secs()
|
||||
);
|
||||
for json_property in json_properties {
|
||||
headset_info_string += &json_property;
|
||||
}
|
||||
|
||||
headset_info_string += "}";
|
||||
|
||||
@@ -379,7 +379,8 @@ pub enum PropertyDescriptorWrapper {
|
||||
}
|
||||
|
||||
pub struct PropertyDescriptor<T: 'static> {
|
||||
pub prefix: &'static str,
|
||||
pub name: &'static str,
|
||||
pub pretty_name: &'static str,
|
||||
pub data: Option<T>,
|
||||
pub suffix: &'static str,
|
||||
pub property_type: PropertyType,
|
||||
@@ -389,7 +390,7 @@ pub struct PropertyDescriptor<T: 'static> {
|
||||
impl<T: Debug> Debug for PropertyDescriptor<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("PropertyDescriptor")
|
||||
.field("prefix", &self.prefix)
|
||||
.field("pretty_name", &self.pretty_name)
|
||||
.field("data", &self.data)
|
||||
.field("suffix", &self.suffix)
|
||||
.field("property_type", &self.property_type)
|
||||
@@ -432,7 +433,8 @@ impl DeviceProperties {
|
||||
pub fn get_properties(&self) -> Vec<PropertyDescriptorWrapper> {
|
||||
vec![
|
||||
PropertyDescriptorWrapper::String(PropertyDescriptor {
|
||||
prefix: "Charging status:",
|
||||
name: "charging_status",
|
||||
pretty_name: "Charging status",
|
||||
data: self.charging.map(|c| c.to_string()),
|
||||
suffix: "",
|
||||
property_type: PropertyType::AlwaysReadOnly,
|
||||
@@ -440,7 +442,8 @@ impl DeviceProperties {
|
||||
}),
|
||||
PropertyDescriptorWrapper::Int(
|
||||
PropertyDescriptor {
|
||||
prefix: "Battery level:",
|
||||
name: "battery_level",
|
||||
pretty_name: "Battery level:",
|
||||
data: self.battery_level,
|
||||
suffix: "%",
|
||||
property_type: PropertyType::AlwaysReadOnly,
|
||||
@@ -449,7 +452,8 @@ impl DeviceProperties {
|
||||
&[],
|
||||
),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Muted:",
|
||||
name: "mic_muted",
|
||||
pretty_name: "Muted:",
|
||||
data: self.muted,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_mute {
|
||||
@@ -460,7 +464,8 @@ impl DeviceProperties {
|
||||
create_event: &move |mute| Some(DeviceEvent::Muted(mute)),
|
||||
}),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Mic connected:",
|
||||
name: "mic_connected",
|
||||
pretty_name: "Mic connected:",
|
||||
data: self.mic_connected,
|
||||
suffix: "",
|
||||
property_type: PropertyType::AlwaysReadOnly,
|
||||
@@ -468,7 +473,8 @@ impl DeviceProperties {
|
||||
}),
|
||||
PropertyDescriptorWrapper::Int(
|
||||
PropertyDescriptor {
|
||||
prefix: "Automatic shutdown after:",
|
||||
name: "automatic_shutdown_interval",
|
||||
pretty_name: "Automatic shutdown after:",
|
||||
data: self
|
||||
.automatic_shutdown_after
|
||||
.map(|t| (t.as_secs() / 60) as u8),
|
||||
@@ -488,7 +494,8 @@ impl DeviceProperties {
|
||||
),
|
||||
PropertyDescriptorWrapper::Int(
|
||||
PropertyDescriptor {
|
||||
prefix: "Pairing info:",
|
||||
name: "pairing_info",
|
||||
pretty_name: "Pairing info:",
|
||||
data: self.pairing_info,
|
||||
suffix: "",
|
||||
property_type: PropertyType::AlwaysReadOnly,
|
||||
@@ -497,14 +504,16 @@ impl DeviceProperties {
|
||||
&[],
|
||||
),
|
||||
PropertyDescriptorWrapper::String(PropertyDescriptor {
|
||||
prefix: "Product color:",
|
||||
name: "product_color",
|
||||
pretty_name: "Product color:",
|
||||
data: self.product_color.map(|c| c.to_string()),
|
||||
suffix: "",
|
||||
property_type: PropertyType::AlwaysReadOnly,
|
||||
create_event: &|_| None,
|
||||
}),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Side tone:",
|
||||
name: "side_tone_enabled",
|
||||
pretty_name: "Side tone:",
|
||||
data: self.side_tone_on,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_side_tone {
|
||||
@@ -516,7 +525,8 @@ impl DeviceProperties {
|
||||
}),
|
||||
PropertyDescriptorWrapper::Int(
|
||||
PropertyDescriptor {
|
||||
prefix: "Side tone volume:",
|
||||
name: "side_tone_volume",
|
||||
pretty_name: "Side tone volume:",
|
||||
data: self.side_tone_volume,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_side_tone_volume {
|
||||
@@ -529,7 +539,8 @@ impl DeviceProperties {
|
||||
&[0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250],
|
||||
),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Surround sound:",
|
||||
name: "surrond_sound_enabled",
|
||||
pretty_name: "Surround sound:",
|
||||
data: self.surround_sound,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_surround_sound {
|
||||
@@ -540,7 +551,8 @@ impl DeviceProperties {
|
||||
create_event: &move |enable| Some(DeviceEvent::SurroundSound(enable)),
|
||||
}),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Voice prompt:",
|
||||
name: "voice_prompt_enabled",
|
||||
pretty_name: "Voice prompt:",
|
||||
data: self.voice_prompt_on,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_voice_prompt {
|
||||
@@ -551,7 +563,8 @@ impl DeviceProperties {
|
||||
create_event: &move |enable| Some(DeviceEvent::VoicePrompt(enable)),
|
||||
}),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Playback muted:",
|
||||
name: "playback_muted",
|
||||
pretty_name: "Playback muted:",
|
||||
data: self.silent,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_silent_mode {
|
||||
@@ -562,7 +575,8 @@ impl DeviceProperties {
|
||||
create_event: &move |enable| Some(DeviceEvent::Silent(enable)),
|
||||
}),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Noise gate active:",
|
||||
name: "noise_gate_enabled",
|
||||
pretty_name: "Noise gate active:",
|
||||
data: self.noise_gate_active,
|
||||
suffix: "",
|
||||
property_type: if self.can_set_noise_gate {
|
||||
@@ -573,7 +587,8 @@ impl DeviceProperties {
|
||||
create_event: &move |enable| Some(DeviceEvent::NoiseGateActive(enable)),
|
||||
}),
|
||||
PropertyDescriptorWrapper::Bool(PropertyDescriptor {
|
||||
prefix: "Connected:",
|
||||
name: "connected",
|
||||
pretty_name: "Connected:",
|
||||
data: self.connected,
|
||||
suffix: "",
|
||||
property_type: PropertyType::AlwaysReadOnly,
|
||||
@@ -588,17 +603,17 @@ impl DeviceProperties {
|
||||
.filter_map(|prop| {
|
||||
let (prefix, data, suffix) = match prop {
|
||||
PropertyDescriptorWrapper::Int(property_descriptor, _) => (
|
||||
property_descriptor.prefix,
|
||||
property_descriptor.pretty_name,
|
||||
&property_descriptor.data.map(|v| v.to_string()),
|
||||
property_descriptor.suffix,
|
||||
),
|
||||
PropertyDescriptorWrapper::Bool(property_descriptor) => (
|
||||
property_descriptor.prefix,
|
||||
property_descriptor.pretty_name,
|
||||
&property_descriptor.data.map(|v| v.to_string()),
|
||||
property_descriptor.suffix,
|
||||
),
|
||||
PropertyDescriptorWrapper::String(property_descriptor) => (
|
||||
property_descriptor.prefix,
|
||||
property_descriptor.pretty_name,
|
||||
&property_descriptor.data,
|
||||
property_descriptor.suffix,
|
||||
),
|
||||
@@ -616,19 +631,19 @@ impl DeviceProperties {
|
||||
.filter_map(|prop| {
|
||||
let (prefix, data, suffix, property_type) = match prop {
|
||||
PropertyDescriptorWrapper::Int(property_descriptor, _) => (
|
||||
property_descriptor.prefix,
|
||||
property_descriptor.pretty_name,
|
||||
&property_descriptor.data.map(|v| v.to_string()),
|
||||
property_descriptor.suffix,
|
||||
property_descriptor.property_type,
|
||||
),
|
||||
PropertyDescriptorWrapper::Bool(property_descriptor) => (
|
||||
property_descriptor.prefix,
|
||||
property_descriptor.pretty_name,
|
||||
&property_descriptor.data.map(|v| v.to_string()),
|
||||
property_descriptor.suffix,
|
||||
property_descriptor.property_type,
|
||||
),
|
||||
PropertyDescriptorWrapper::String(property_descriptor) => (
|
||||
property_descriptor.prefix,
|
||||
property_descriptor.pretty_name,
|
||||
&property_descriptor.data,
|
||||
property_descriptor.suffix,
|
||||
property_descriptor.property_type,
|
||||
@@ -641,7 +656,10 @@ impl DeviceProperties {
|
||||
} else {
|
||||
""
|
||||
};
|
||||
format!("{:<padding$} {}{}{}", prefix, data, suffix, readonly_marker)
|
||||
format!(
|
||||
"{:<padding$}: {}{}{}",
|
||||
prefix, data, suffix, readonly_marker
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
|
||||
@@ -140,8 +140,8 @@ impl Tray for StatusTray {
|
||||
menu_items.push(
|
||||
StandardItem {
|
||||
label: format!(
|
||||
"{} {}{}",
|
||||
property.prefix, current_value, property.suffix
|
||||
"{}: {}{}",
|
||||
property.pretty_name, current_value, property.suffix
|
||||
),
|
||||
enabled: false,
|
||||
activate: Box::new(move |_| {
|
||||
@@ -179,7 +179,7 @@ impl Tray for StatusTray {
|
||||
SubMenu {
|
||||
label: format!(
|
||||
"{} {}{}",
|
||||
property.prefix, current_value, property.suffix
|
||||
property.pretty_name, current_value, property.suffix
|
||||
),
|
||||
enabled: property.property_type == PropertyType::ReadWrite
|
||||
&& property.data.is_some(),
|
||||
@@ -199,7 +199,7 @@ impl Tray for StatusTray {
|
||||
StandardItem {
|
||||
label: format!(
|
||||
"{} {}{}",
|
||||
property.prefix, current_value, property.suffix
|
||||
property.pretty_name, current_value, property.suffix
|
||||
),
|
||||
enabled: property.property_type == PropertyType::ReadWrite
|
||||
&& property.data.is_some(),
|
||||
@@ -222,7 +222,7 @@ impl Tray for StatusTray {
|
||||
StandardItem {
|
||||
label: format!(
|
||||
"{} {}{}",
|
||||
property.prefix, current_value, property.suffix
|
||||
property.pretty_name, current_value, property.suffix
|
||||
),
|
||||
enabled: false,
|
||||
activate: Box::new(move |_| {
|
||||
|
||||
Reference in New Issue
Block a user