blob: 13f61f75849191945c0fff88ea1f58e57147f086 [file] [log] [blame]
// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Helpers to serialize fuchsia_audio types with serde.
use fuchsia_audio::{
device::{ClockDomain, GainCapabilities, GainState},
format::SampleType,
format_set::{ChannelAttributes, ChannelSet, PcmFormatSet},
};
use serde::{ser::SerializeSeq, Serialize, Serializer};
/// Serialize an optional value that can be converted to a string to either the string, or none.
pub fn serialize_option_tostring<S>(
value: &Option<impl ToString>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let Some(value) = value else { return serializer.serialize_none() };
serializer.serialize_str(&value.to_string())
}
/// Serialize a vector of values that can be converted to a string to either a sequence
/// of strings, or none.
pub fn serialize_vec_tostring<S>(
value: &Vec<impl ToString>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(value.len()))?;
for item in value {
seq.serialize_element(&item.to_string())?;
}
seq.end()
}
/// Serialize an optional [ClockDomain] to its number value, or none.
pub fn serialize_option_clockdomain<S>(
clock_domain: &Option<ClockDomain>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let Some(clock_domain) = clock_domain else { return serializer.serialize_none() };
serializer.serialize_u32(clock_domain.0)
}
// Mirror type for serialization.
// This exists to avoid the fuchsia-audio library from depending on serde.
#[derive(Serialize)]
#[serde(remote = "GainState")]
pub struct GainStateDef {
pub gain_db: f32,
pub muted: Option<bool>,
pub agc_enabled: Option<bool>,
}
pub fn serialize_option_gainstate<S>(
gain_state: &Option<GainState>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let Some(gain_state) = gain_state else { return serializer.serialize_none() };
GainStateDef::serialize(gain_state, serializer)
}
// Mirror type for serialization.
// This exists to avoid the fuchsia-audio library from depending on serde.
#[derive(Serialize)]
#[serde(remote = "GainCapabilities")]
pub struct GainCapabilitiesDef {
pub min_gain_db: f32,
pub max_gain_db: f32,
pub gain_step_db: f32,
pub can_mute: Option<bool>,
pub can_agc: Option<bool>,
}
pub fn serialize_option_gaincapabilities<S>(
gain_caps: &Option<GainCapabilities>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let Some(gain_caps) = gain_caps else { return serializer.serialize_none() };
GainCapabilitiesDef::serialize(gain_caps, serializer)
}
// Mirror type for serialization.
// This exists to avoid the fuchsia-audio library from depending on serde.
#[derive(Serialize)]
#[serde(remote = "PcmFormatSet")]
pub struct PcmFormatSetDef {
#[serde(serialize_with = "serialize_vec_channelset")]
pub channel_sets: Vec<ChannelSet>,
#[serde(serialize_with = "serialize_vec_tostring")]
pub sample_types: Vec<SampleType>,
pub frame_rates: Vec<u32>,
}
pub fn serialize_option_vec_pcmformatset<S>(
format_sets: &Option<Vec<PcmFormatSet>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let Some(format_sets) = format_sets else { return serializer.serialize_none() };
#[derive(Serialize)]
struct Wrapper<'a>(#[serde(with = "PcmFormatSetDef")] &'a PcmFormatSet);
let mut seq = serializer.serialize_seq(Some(format_sets.len()))?;
for format_set in format_sets {
seq.serialize_element(&Wrapper(format_set))?;
}
seq.end()
}
// Mirror type for serialization.
// This exists to avoid the fuchsia-audio library from depending on serde.
#[derive(Serialize)]
#[serde(remote = "ChannelSet")]
pub struct ChannelSetDef {
#[serde(serialize_with = "serialize_vec_channelattributes")]
pub attributes: Vec<ChannelAttributes>,
}
pub fn serialize_vec_channelset<S>(
channel_sets: &Vec<ChannelSet>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
struct Wrapper<'a>(#[serde(with = "ChannelSetDef")] &'a ChannelSet);
let mut seq = serializer.serialize_seq(Some(channel_sets.len()))?;
for channel_set in channel_sets {
seq.serialize_element(&Wrapper(channel_set))?;
}
seq.end()
}
// Mirror type for serialization.
// This exists to avoid the fuchsia-audio library from depending on serde.
#[derive(Serialize)]
#[serde(remote = "ChannelAttributes")]
pub struct ChannelAttributesDef {
pub min_frequency: Option<u32>,
pub max_frequency: Option<u32>,
}
pub fn serialize_vec_channelattributes<S>(
channel_attributes: &Vec<ChannelAttributes>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
struct Wrapper<'a>(#[serde(with = "ChannelAttributesDef")] &'a ChannelAttributes);
let mut seq = serializer.serialize_seq(Some(channel_attributes.len()))?;
for attributes in channel_attributes {
seq.serialize_element(&Wrapper(attributes))?;
}
seq.end()
}