Skip to content

Commit

Permalink
feat(spa): SpaJson serde impls
Browse files Browse the repository at this point in the history
  • Loading branch information
arcnmx committed Jun 8, 2024
1 parent 3ddf26e commit 807d4c8
Show file tree
Hide file tree
Showing 13 changed files with 2,592 additions and 87 deletions.
34 changes: 32 additions & 2 deletions Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -277,26 +277,56 @@ version = "" # fails to parse, so removes cfg
[[object]]
name = "Wp.SpaJson"
status = "generate"
trust_return_value_nullability = true
[[object.function]]
pattern = "(.*valist|new_array|new_object|object_get|parse_array|parse_object)"
ignore = true
[[object.function]]
pattern = "(new_wrap|spa_json)"
pattern = "(new_wrap|new_from_string|get_spa_json|get_data)"
manual = true
[[object.function]]
name = "new_from_stringn"
rename = "new_from_string"
manual = true
[[object.function]]
name = "to_string"
ignore = true
[[object.function]]
name = "ensure_unique_owner"
[[object.function.return]]
nullable = false

[[object]]
name = "Wp.SpaJsonParser"
status = "generate"
[[object.function]]
pattern = "(get|get_valist)"
ignore = true
[[object.function]]
pattern = "(get_json)"
manual = true
[[object.function]]
name = "get_null"
rename = "null"
[[object.function]]
name = "new_array"
rename = "new_array_unchecked"
unsafe = true
[[object.function]]
name = "new_object"
rename = "new_object_unchecked"
unsafe = true

[[object]]
name = "Wp.SpaJsonBuilder"
status = "generate"
trust_return_value_nullability = true
[[object.function]]
pattern = "(add|add_valist)"
pattern = "(add|add_valist|add_from_string)"
ignore = true
[[object.function]]
name = "add_from_stringn"
rename = "add_from_string"

[[object]]
name = "Wp.SpaPod"
Expand Down
12 changes: 9 additions & 3 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ path = "src/static-link.rs"

[dependencies]
futures = "0.3"
wireplumber = { version = "0.1", features = ["futures", "glib-signal", "serde", "v0_4_3"], path = "../" }
wireplumber = { version = "0.1", features = ["futures", "glib-signal", "v0_4_3"], path = "../" }
pipewire-sys = "0.7"
glib = { version = "0.19" }
ctrlc = { version = "3.0", features = ["termination"] }
once_cell = { version = "1.19" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
clap = { version = "3.0", features = ["derive"] }
anyhow = "1.0"

[features]
default = ["spa-json"]
spa-json = ["wireplumber/v0_4_8", "serde"]
serde = ["dep:serde", "wireplumber/serde"]
serde_json = ["serde", "dep:serde_json"]
5 changes: 5 additions & 0 deletions examples/src/bin/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
//!
//! Roughly based on the original [wpexec.c](https://gitlab.freedesktop.org/pipewire/wireplumber/-/blob/master/src/tools/wpexec.c)
#[cfg(feature = "spa-json")]
use wireplumber::spa::SpaJson;
use {
anyhow::{format_err, Context, Result},
clap::{ArgEnum, Parser},
Expand Down Expand Up @@ -270,6 +272,9 @@ impl Args {
fn variant(&self) -> Result<Option<LuaVariant>> {
match self.json_arg {
None => Ok(None),
#[cfg(feature = "spa-json")]
Some(ref json) => SpaJson::deserialize_from_string(json).map_err(Into::into).map(Some),
#[cfg(all(feature = "serde_json", not(feature = "spa-json")))]
Some(ref json) => serde_json::from_str(json).map_err(Into::into).map(Some),
}
}
Expand Down
26 changes: 20 additions & 6 deletions examples/src/static-link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
//! recommended. Additional explanation and documentation is located in the [plugin module
//! documentation](wireplumber::plugin).
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use {
futures::{channel::mpsc, future, FutureExt, StreamExt},
glib::{prelude::*, Error, SourceId, Variant},
once_cell::unsync::OnceCell,
serde::{Deserialize, Serialize},
std::{future::Future, iter, pin::Pin},
wireplumber::{
core::{Object, ObjectFeatures},
Expand All @@ -29,7 +30,8 @@ const LOG_DOMAIN: &'static str = "static-link";

/// A list of user-specified [Constraints](Constraint)
/// used to find each end of the port to be linked.
#[derive(Debug, Clone, Deserialize, Serialize, Variant)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct PortMapping {
/// A description of the output ports to link.
///
Expand All @@ -43,31 +45,33 @@ pub struct PortMapping {

/// serde boolean default
#[doc(hidden)]
#[cfg(feature = "serde")]
fn true_() -> bool {
true
}

/// User configuration for the [StaticLink] plugin
#[derive(Debug, Clone, Deserialize, Serialize, Variant)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct StaticLinkArgs {
/// The source node to link to `input`
output: Vec<Constraint>,
/// The sink node to link to `output`
input: Vec<Constraint>,
/// Describes how to link the ports of the `input` node to the `output`
#[serde(default, rename = "mappings")]
#[cfg_attr(feature = "serde", serde(default, rename = "mappings"))]
port_mappings: Vec<PortMapping>,
/// Whether to mark any created links as `link.passive`
///
/// Defaults to `true`
#[serde(default = "true_")]
#[cfg_attr(feature = "serde", serde(default = "true_"))]
passive: bool,
/// Whether to mark any created links as `object.linger`
///
/// A lingering link will remain in place even after this module's parent process has exited.
///
/// Defaults to `true`
#[serde(default = "true_")]
#[cfg_attr(feature = "serde", serde(default = "true_"))]
linger: bool,
}

Expand Down Expand Up @@ -290,12 +294,22 @@ impl SimplePlugin for StaticLink {
self.args.set(args).unwrap();
}

#[cfg(feature = "serde")]
fn decode_args(args: Option<Variant>) -> Result<Self::Args, Error> {
args
.map(|args| from_variant(&args))
.unwrap_or(Ok(Default::default()))
.map_err(error::invalid_argument)
}

#[cfg(not(feature = "serde"))]
fn decode_args(args: Option<Variant>) -> Result<Self::Args, Error> {
let args = args.map(|_args| {
warning!(domain: LOG_DOMAIN, "requires serde build feature");
Default::default()
});
Ok(args.unwrap_or_default())
}
}

// macros take care of entry point boilerplate by impl'ing a bunch of traits for us
Expand Down
60 changes: 4 additions & 56 deletions src/auto/spa_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,6 @@ impl SpaJson {
}
}

#[doc(alias = "wp_spa_json_new_from_string")]
#[doc(alias = "new_from_string")]
pub fn from_string(json_str: &str) -> SpaJson {
unsafe {
from_glib_full(ffi::wp_spa_json_new_from_string(json_str.to_glib_none().0))
}
}

#[cfg(feature = "v0_4_10")]
#[cfg_attr(docsrs, doc(cfg(feature = "v0_4_10")))]
#[doc(alias = "wp_spa_json_new_from_stringn")]
#[doc(alias = "new_from_stringn")]
pub fn from_stringn(json_str: &str) -> SpaJson {
let len = json_str.len() as _;
unsafe {
from_glib_full(ffi::wp_spa_json_new_from_stringn(json_str.to_glib_none().0, len))
}
}

#[doc(alias = "wp_spa_json_new_int")]
pub fn new_int(value: i32) -> SpaJson {
unsafe {
Expand All @@ -72,28 +53,20 @@ impl SpaJson {

#[doc(alias = "wp_spa_json_copy")]
#[must_use]
pub fn copy(&self) -> Option<SpaJson> {
pub fn copy(&self) -> SpaJson {
unsafe {
from_glib_full(ffi::wp_spa_json_copy(self.to_glib_none().0))
}
}

#[doc(alias = "wp_spa_json_ensure_unique_owner")]
#[must_use]
pub fn ensure_unique_owner(self) -> Option<SpaJson> {
pub fn ensure_unique_owner(self) -> SpaJson {
unsafe {
from_glib_full(ffi::wp_spa_json_ensure_unique_owner(self.into_glib_ptr()))
}
}

#[doc(alias = "wp_spa_json_get_data")]
#[doc(alias = "get_data")]
pub fn data(&self) -> Option<glib::GString> {
unsafe {
from_glib_none(ffi::wp_spa_json_get_data(self.to_glib_none().0))
}
}

#[doc(alias = "wp_spa_json_get_size")]
#[doc(alias = "get_size")]
pub fn size(&self) -> usize {
Expand All @@ -102,12 +75,6 @@ impl SpaJson {
}
}

//#[doc(alias = "wp_spa_json_get_spa_json")]
//#[doc(alias = "get_spa_json")]
//pub fn spa_json(&self) -> /*Unimplemented*/Option<Basic: Pointer> {
// unsafe { TODO: call ffi:wp_spa_json_get_spa_json() }
//}

#[doc(alias = "wp_spa_json_is_array")]
pub fn is_array(&self) -> bool {
unsafe {
Expand Down Expand Up @@ -165,7 +132,7 @@ impl SpaJson {
}

#[doc(alias = "wp_spa_json_new_iterator")]
pub fn new_iterator(&self) -> Option<Iterator> {
pub fn new_iterator(&self) -> Iterator {
unsafe {
from_glib_full(ffi::wp_spa_json_new_iterator(self.to_glib_none().0))
}
Expand Down Expand Up @@ -199,28 +166,9 @@ impl SpaJson {
}

#[doc(alias = "wp_spa_json_parse_string")]
pub fn parse_string(&self) -> Option<glib::GString> {
pub fn parse_string(&self) -> glib::GString {
unsafe {
from_glib_full(ffi::wp_spa_json_parse_string(self.to_glib_none().0))
}
}

#[cfg(feature = "v0_4_11")]
#[cfg_attr(docsrs, doc(cfg(feature = "v0_4_11")))]
#[doc(alias = "wp_spa_json_to_string")]
#[doc(alias = "to_string")]
pub fn to_str(&self) -> glib::GString {
unsafe {
from_glib_full(ffi::wp_spa_json_to_string(self.to_glib_none().0))
}
}
}

#[cfg(feature = "v0_4_11")]
#[cfg_attr(docsrs, doc(cfg(feature = "v0_4_11")))]
impl std::fmt::Display for SpaJson {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_str(&self.to_str())
}
}
2 changes: 1 addition & 1 deletion src/auto/spa_json_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl SpaJsonBuilder {
}

#[doc(alias = "wp_spa_json_builder_end")]
pub fn end(&self) -> Option<SpaJson> {
pub fn end(&self) -> SpaJson {
unsafe {
from_glib_full(ffi::wp_spa_json_builder_end(self.to_glib_none().0))
}
Expand Down
24 changes: 7 additions & 17 deletions src/auto/spa_json_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,15 @@ glib::wrapper! {

impl SpaJsonParser {
#[doc(alias = "wp_spa_json_parser_new_array")]
pub fn new_array(json: &SpaJson) -> SpaJsonParser {
unsafe {
from_glib_full(ffi::wp_spa_json_parser_new_array(json.to_glib_none().0))
}
#[doc(alias = "new_array")]
pub unsafe fn new_array_unchecked(json: &SpaJson) -> SpaJsonParser {
from_glib_full(ffi::wp_spa_json_parser_new_array(json.to_glib_none().0))
}

#[doc(alias = "wp_spa_json_parser_new_object")]
pub fn new_object(json: &SpaJson) -> SpaJsonParser {
unsafe {
from_glib_full(ffi::wp_spa_json_parser_new_object(json.to_glib_none().0))
}
#[doc(alias = "new_object")]
pub unsafe fn new_object_unchecked(json: &SpaJson) -> SpaJsonParser {
from_glib_full(ffi::wp_spa_json_parser_new_object(json.to_glib_none().0))
}

#[doc(alias = "wp_spa_json_parser_end")]
Expand Down Expand Up @@ -67,17 +65,9 @@ impl SpaJsonParser {
}
}

#[doc(alias = "wp_spa_json_parser_get_json")]
#[doc(alias = "get_json")]
pub fn json(&self) -> Option<SpaJson> {
unsafe {
from_glib_full(ffi::wp_spa_json_parser_get_json(self.to_glib_none().0))
}
}

#[doc(alias = "wp_spa_json_parser_get_null")]
#[doc(alias = "get_null")]
pub fn is_null(&self) -> bool {
pub fn null(&self) -> bool {
unsafe {
from_glib(ffi::wp_spa_json_parser_get_null(self.to_glib_none().0))
}
Expand Down
3 changes: 2 additions & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ pub(crate) use {
glib::{
error::ErrorDomain,
ffi::{gconstpointer, gpointer},
gstr,
object::{Cast, IsA, Object as GObject, ObjectExt as GObjectExt, ObjectType},
translate::*,
types::{Pointee, Pointer, StaticType},
value::{FromValue, ToValue},
variant::{FromVariant, StaticVariantType, ToVariant},
Type, Value, Variant, VariantClass, VariantTy,
GStr, GString, Type, Value, Variant, VariantClass, VariantTy,
},
std::{
borrow::{Borrow, Cow},
Expand Down
1 change: 0 additions & 1 deletion src/spa/json.rs

This file was deleted.

Loading

0 comments on commit 807d4c8

Please sign in to comment.