Created
June 5, 2023 20:01
-
-
Save saivert/d46b947db914f829026dd0827416fa52 to your computer and use it in GitHub Desktop.
Serialization and Deserialization of pipewire Props
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct SomeProps { | |
volume: Option<f32>, | |
mute: Option<bool>, | |
channel_volumes: Option<Vec<f32>>, | |
} | |
const PROPS_KEY_CHANNEL_VOLUMES: u32 = 65544; | |
const PROPS_KEY_VOLUME: u32 = 65539; | |
const PROPS_KEY_MUTE: u32 = 65540; | |
impl<'de> PodDeserialize<'de> for SomeProps { | |
fn deserialize( | |
deserializer: PodDeserializer<'de>, | |
) -> Result<(Self, DeserializeSuccess<'de>), DeserializeError<&'de [u8]>> | |
where | |
Self: Sized, | |
{ | |
use pipewire::spa::pod::{Value, ValueArray}; | |
struct ObjectVisitor; | |
impl<'de> Visitor<'de> for ObjectVisitor { | |
type Value = SomeProps; | |
type ArrayElem = std::convert::Infallible; | |
fn visit_object( | |
&self, | |
object_deserializer: &mut ObjectPodDeserializer<'de>, | |
) -> Result<Self::Value, DeserializeError<&'de [u8]>> { | |
let mut tmp = SomeProps { | |
channel_volumes: None, | |
volume: None, | |
mute: None, | |
}; | |
while let Some((value, key, _flags)) = | |
object_deserializer.deserialize_property::<Value>()? | |
{ | |
match key { | |
PROPS_KEY_CHANNEL_VOLUMES => { | |
if let Value::ValueArray(ValueArray::Float(channel_volumes)) = &value { | |
dbg!(channel_volumes); | |
tmp.channel_volumes = Some(channel_volumes.clone()); | |
} | |
} | |
PROPS_KEY_VOLUME => { | |
if let Value::Float(volume) = &value { | |
tmp.volume = Some(volume.clone()); | |
} | |
} | |
PROPS_KEY_MUTE => { | |
if let Value::Bool(mute) = &value { | |
tmp.mute = Some(mute.clone()); | |
} | |
} | |
_ => {} | |
} | |
} | |
Ok(tmp) | |
} | |
} | |
deserializer.deserialize_object(ObjectVisitor) | |
} | |
} | |
impl PodSerialize for SomeProps { | |
fn serialize<O: io::Write + io::Seek>( | |
&self, | |
serializer: PodSerializer<O>, | |
) -> Result<SerializeSuccess<O>, GenError> { | |
use pipewire::spa::pod::{Value, ValueArray}; | |
const OBJECT_TYPE_PROPS: u32 = 262146; | |
const OBJECT_ID_PROPS: u32 = 2; | |
let mut object_serializer = serializer.serialize_object(OBJECT_TYPE_PROPS, OBJECT_ID_PROPS)?; | |
if let Some(channel_volumes) = &self.channel_volumes { | |
object_serializer.serialize_property( | |
PROPS_KEY_CHANNEL_VOLUMES, | |
&Value::ValueArray(ValueArray::Float(channel_volumes.clone())), | |
pipewire::spa::pod::PropertyFlags::empty())?; | |
} | |
if let Some(volume) = &self.volume { | |
object_serializer.serialize_property( | |
PROPS_KEY_VOLUME, | |
&Value::Float(*volume), | |
pipewire::spa::pod::PropertyFlags::empty())?; | |
} | |
if let Some(mute) = &self.mute { | |
object_serializer.serialize_property( | |
PROPS_KEY_MUTE, | |
&Value::Bool(*mute), | |
pipewire::spa::pod::PropertyFlags::empty())?; | |
} | |
object_serializer.end() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment