mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-28 20:41:31 +00:00
Add De/Serialization for most bitflag types
Represents combinations of flags with a '+' separated string of nicks, or an empty string for no flags set. Note that most flag types will ignore any flags using multiple bits when serializing, since in most cases these flags cover all used bits.
This commit is contained in:
parent
94b5a13f4b
commit
1b22be2e15
34 changed files with 1631 additions and 158 deletions
|
@ -221,11 +221,14 @@ plugins-update-nightly:
|
||||||
- |
|
- |
|
||||||
get_features() {
|
get_features() {
|
||||||
crate=$1
|
crate=$1
|
||||||
if [ "$crate" = "gstreamer" ]; then
|
case "$crate" in
|
||||||
echo "--features=ser_de,v1_22"
|
gstreamer-audio|gstreamer-editing-services|gstreamer-gl|gstreamer-pbutils|gstreamer-rtp|gstreamer-rtsp|gstreamer-video|gstreamer)
|
||||||
else
|
echo "--features=ser_de,v1_22"
|
||||||
echo "--features=v1_22"
|
;;
|
||||||
fi
|
*)
|
||||||
|
echo "--features=v1_22"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
for crate in gstreamer* gstreamer-gl/{egl,wayland,x11}; do
|
for crate in gstreamer* gstreamer-gl/{egl,wayland,x11}; do
|
||||||
if [ -e $crate/Cargo.toml ]; then
|
if [ -e $crate/Cargo.toml ]; then
|
||||||
|
@ -368,11 +371,14 @@ clippy:
|
||||||
- |
|
- |
|
||||||
get_features() {
|
get_features() {
|
||||||
crate=$1
|
crate=$1
|
||||||
if [ "$crate" = "gstreamer" ]; then
|
case "$crate" in
|
||||||
echo "--features=ser_de,v1_22"
|
gstreamer-audio|gstreamer-editing-services|gstreamer-gl|gstreamer-pbutils|gstreamer-rtp|gstreamer-rtsp|gstreamer-video|gstreamer)
|
||||||
else
|
echo "--features=ser_de,v1_22"
|
||||||
echo "--features=v1_22"
|
;;
|
||||||
fi
|
*)
|
||||||
|
echo "--features=v1_22"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
for crate in gstreamer* gstreamer-gl/{egl,wayland,x11}; do
|
for crate in gstreamer* gstreamer-gl/{egl,wayland,x11}; do
|
||||||
if [ -e $crate/Cargo.toml ]; then
|
if [ -e $crate/Cargo.toml ]; then
|
||||||
|
|
|
@ -23,9 +23,11 @@ gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
||||||
array-init = "2.0"
|
array-init = "2.0"
|
||||||
once_cell = "1.0"
|
once_cell = "1.0"
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
|
serde_json = "1.0"
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -34,7 +36,8 @@ v1_16 = ["gst/v1_16", "gst-base/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "gst-base/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-base/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-base/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-base/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "gst-base/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "gst-base/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
76
gstreamer-audio/src/flag_serde.rs
Normal file
76
gstreamer-audio/src/flag_serde.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::AudioFlags);
|
||||||
|
bitflags_serde_impl!(crate::AudioFormatFlags);
|
||||||
|
bitflags_serde_impl!(crate::AudioPackFlags);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::AudioFlags::all(), "\"unpositioned\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::AudioFormatFlags::all(),
|
||||||
|
"\"integer+float+signed+complex+unpack\""
|
||||||
|
);
|
||||||
|
check_serialize!(crate::AudioPackFlags::all(), "\"truncate-range\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::AudioFlags,
|
||||||
|
crate::AudioFlags::all(),
|
||||||
|
"\"unpositioned\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::AudioFormatFlags,
|
||||||
|
crate::AudioFormatFlags::all(),
|
||||||
|
"\"integer+float+signed+complex+unpack\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::AudioPackFlags,
|
||||||
|
crate::AudioPackFlags::all(),
|
||||||
|
"\"truncate-range\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(crate::AudioFlags, crate::AudioFlags::all());
|
||||||
|
check_roundtrip!(crate::AudioFormatFlags, crate::AudioFormatFlags::all());
|
||||||
|
check_roundtrip!(crate::AudioPackFlags, crate::AudioPackFlags::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,9 @@ macro_rules! skip_assert_initialized {
|
||||||
mod auto;
|
mod auto;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
mod audio_format;
|
mod audio_format;
|
||||||
pub use crate::audio_format::*;
|
pub use crate::audio_format::*;
|
||||||
mod audio_format_info;
|
mod audio_format_info;
|
||||||
|
|
|
@ -22,16 +22,19 @@ gio = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
||||||
gst-pbutils = { package = "gstreamer-pbutils", path = "../gstreamer-pbutils" }
|
gst-pbutils = { package = "gstreamer-pbutils", path = "../gstreamer-pbutils" }
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
v1_16 = ["gst/v1_16", "gst-base/v1_16", "gst-pbutils/v1_16", "ffi/v1_16"]
|
v1_16 = ["gst/v1_16", "gst-base/v1_16", "gst-pbutils/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "gst-base/v1_18", "gst-pbutils/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-base/v1_18", "gst-pbutils/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-base/v1_20", "gst-pbutils/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-base/v1_20", "gst-pbutils/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "gst-base/v1_22", "gst-pbutils/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "gst-base/v1_22", "gst-pbutils/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gio/dox", "gst/dox", "gst-base/dox", "gst-pbutils/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gio/dox", "gst/dox", "gst-base/dox", "gst-pbutils/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de", "gst-pbutils/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
90
gstreamer-editing-services/src/flag_serde.rs
Normal file
90
gstreamer-editing-services/src/flag_serde.rs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::MarkerFlags, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::MetaFlag);
|
||||||
|
bitflags_serde_impl!(crate::PipelineFlags);
|
||||||
|
bitflags_serde_impl!(crate::TrackType);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(crate::MarkerFlags::all(), "\"snappable\"");
|
||||||
|
check_serialize!(crate::MetaFlag::all(), "\"readable+writable\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::PipelineFlags::all(),
|
||||||
|
"\"audio_preview+video_preview+render+smart_render\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::TrackType::all(),
|
||||||
|
"\"unknown+audio+video+text+custom\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::MarkerFlags,
|
||||||
|
crate::MarkerFlags::all(),
|
||||||
|
"\"snappable\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::MetaFlag,
|
||||||
|
crate::MetaFlag::all(),
|
||||||
|
"\"readable+writable\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PipelineFlags,
|
||||||
|
crate::PipelineFlags::all(),
|
||||||
|
"\"audio_preview+video_preview+render+smart_render\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::TrackType,
|
||||||
|
crate::TrackType::all(),
|
||||||
|
"\"unknown+audio+video+text+custom\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(crate::MarkerFlags, crate::MarkerFlags::all());
|
||||||
|
check_roundtrip!(crate::MetaFlag, crate::MetaFlag::all());
|
||||||
|
check_roundtrip!(crate::PipelineFlags, crate::PipelineFlags::all());
|
||||||
|
check_roundtrip!(crate::TrackType, crate::TrackType::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,6 +62,9 @@ macro_rules! skip_assert_initialized {
|
||||||
mod auto;
|
mod auto;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
// Re-export all the traits in a prelude module, so that applications
|
// Re-export all the traits in a prelude module, so that applications
|
||||||
// can always "use ges::prelude::*" without getting conflicts
|
// can always "use ges::prelude::*" without getting conflicts
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
|
|
@ -26,9 +26,11 @@ glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
gst-base = { package = "gstreamer-base", path = "../gstreamer-base" }
|
||||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
|
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -36,7 +38,8 @@ v1_16 = ["gst/v1_16", "gst-base/v1_16", "gst-video/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "gst-base/v1_18", "gst-video/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-base/v1_18", "gst-video/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-base/v1_20", "gst-video/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-base/v1_20", "gst-video/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "gst-base/v1_22", "gst-video/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "gst-base/v1_22", "gst-video/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox", "gst-video/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox", "gst-video/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de", "gst-video/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
110
gstreamer-gl/src/flag_serde.rs
Normal file
110
gstreamer-gl/src/flag_serde.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::GLAPI);
|
||||||
|
bitflags_serde_impl!(crate::GLConfigSurfaceType, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::GLDisplayType);
|
||||||
|
bitflags_serde_impl!(crate::GLPlatform);
|
||||||
|
bitflags_serde_impl!(crate::GLSLProfile);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::GLAPI::all(), "\"opengl+opengl3+gles1+gles2\"");
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::GLConfigSurfaceType::all(),
|
||||||
|
"\"window+pbuffer+pixmap\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::GLDisplayType::all(),
|
||||||
|
concat!(
|
||||||
|
"\"x11+wayland+cocoa+win32+dispmanx+egl+viv-fb+gbm+egl-device",
|
||||||
|
"+eagl+winrt+android\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(crate::GLPlatform::all(), "\"egl+glx+wgl+cgl+eagl\"");
|
||||||
|
check_serialize!(crate::GLSLProfile::all(), "\"es+core+compatibility\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::GLAPI,
|
||||||
|
crate::GLAPI::all(),
|
||||||
|
"\"opengl+opengl3+gles1+gles2\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::GLConfigSurfaceType,
|
||||||
|
crate::GLConfigSurfaceType::all(),
|
||||||
|
"\"none+window+pbuffer+pixmap\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::GLDisplayType,
|
||||||
|
crate::GLDisplayType::all(),
|
||||||
|
concat!(
|
||||||
|
"\"x11+wayland+cocoa+win32+dispmanx+egl+viv-fb+gbm+egl-device",
|
||||||
|
"+eagl+winrt+android\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::GLPlatform,
|
||||||
|
crate::GLPlatform::all(),
|
||||||
|
"\"egl+glx+wgl+cgl+eagl\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::GLSLProfile,
|
||||||
|
crate::GLSLProfile::all(),
|
||||||
|
"\"es+core+compatibility\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(crate::GLAPI, crate::GLAPI::all());
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::GLConfigSurfaceType,
|
||||||
|
crate::GLConfigSurfaceType::all()
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(crate::GLDisplayType, crate::GLDisplayType::all());
|
||||||
|
check_roundtrip!(crate::GLPlatform, crate::GLPlatform::all());
|
||||||
|
check_roundtrip!(crate::GLSLProfile, crate::GLSLProfile::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,9 @@ mod auto;
|
||||||
pub use crate::auto::functions::*;
|
pub use crate::auto::functions::*;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
mod caps_features;
|
mod caps_features;
|
||||||
pub use crate::caps_features::CAPS_FEATURES_MEMORY_GL_MEMORY;
|
pub use crate::caps_features::CAPS_FEATURES_MEMORY_GL_MEMORY;
|
||||||
mod context;
|
mod context;
|
||||||
|
|
|
@ -20,9 +20,11 @@ ffi = { package = "gstreamer-pbutils-sys", path = "sys" }
|
||||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -30,7 +32,8 @@ v1_16 = ["gst/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
77
gstreamer-pbutils/src/flag_serde.rs
Normal file
77
gstreamer-pbutils/src/flag_serde.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::DiscovererSerializeFlags);
|
||||||
|
bitflags_serde_impl!(crate::PbUtilsCapsDescriptionFlags, "v1_20");
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::DiscovererSerializeFlags::all(), "\"caps+tags+misc\"");
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::PbUtilsCapsDescriptionFlags::all(),
|
||||||
|
"\"container+audio+video+image+subtitle+tag+generic\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DiscovererSerializeFlags,
|
||||||
|
crate::DiscovererSerializeFlags::all(),
|
||||||
|
"\"caps+tags+misc\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PbUtilsCapsDescriptionFlags,
|
||||||
|
crate::PbUtilsCapsDescriptionFlags::all(),
|
||||||
|
"\"container+audio+video+image+subtitle+tag+generic\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::DiscovererSerializeFlags,
|
||||||
|
crate::DiscovererSerializeFlags::all()
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::PbUtilsCapsDescriptionFlags,
|
||||||
|
crate::PbUtilsCapsDescriptionFlags::all()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,9 @@ mod auto;
|
||||||
pub use crate::auto::functions::*;
|
pub use crate::auto::functions::*;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
mod discoverer;
|
mod discoverer;
|
||||||
pub use crate::discoverer::*;
|
pub use crate::discoverer::*;
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,11 @@ libc = "0.2"
|
||||||
ffi = { package = "gstreamer-rtp-sys", path = "sys" }
|
ffi = { package = "gstreamer-rtp-sys", path = "sys" }
|
||||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -30,7 +32,8 @@ v1_16 = ["gst/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
114
gstreamer-rtp/src/flag_serde.rs
Normal file
114
gstreamer-rtp/src/flag_serde.rs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::{bitflags_deserialize_impl, bitflags_serde_impl, bitflags_serialize_impl};
|
||||||
|
|
||||||
|
bitflags_serialize_impl!(crate::RTPBufferFlags, by_ones_decreasing);
|
||||||
|
bitflags_deserialize_impl!(crate::RTPBufferFlags);
|
||||||
|
bitflags_serde_impl!(crate::RTPBufferMapFlags);
|
||||||
|
// use this implementation, since serializing to "sendonly+recvonly"
|
||||||
|
// wouldn't make much sense
|
||||||
|
bitflags_serialize_impl!(
|
||||||
|
crate::RTPHeaderExtensionDirection,
|
||||||
|
by_ones_decreasing,
|
||||||
|
"v1_20"
|
||||||
|
);
|
||||||
|
bitflags_deserialize_impl!(crate::RTPHeaderExtensionDirection, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::RTPHeaderExtensionFlags, "v1_20");
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::RTPBufferFlags::all(), "\"retransmission+redundant\"");
|
||||||
|
check_serialize!(crate::RTPBufferMapFlags::all(), "\"skip-padding\"");
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::RTPHeaderExtensionDirection::all(),
|
||||||
|
"\"sendrecv+inherited\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::RTPHeaderExtensionDirection::INACTIVE
|
||||||
|
| crate::RTPHeaderExtensionDirection::SENDONLY
|
||||||
|
| crate::RTPHeaderExtensionDirection::INHERITED,
|
||||||
|
"\"sendonly+inherited\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::RTPHeaderExtensionFlags::all(),
|
||||||
|
"\"one-byte+two-byte\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTPBufferFlags,
|
||||||
|
crate::RTPBufferFlags::all(),
|
||||||
|
"\"retransmission+redundant\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTPBufferMapFlags,
|
||||||
|
crate::RTPBufferMapFlags::all(),
|
||||||
|
"\"skip-padding\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTPHeaderExtensionDirection,
|
||||||
|
crate::RTPHeaderExtensionDirection::all(),
|
||||||
|
"\"sendrecv+inactive+inherited\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTPHeaderExtensionFlags,
|
||||||
|
crate::RTPHeaderExtensionFlags::all(),
|
||||||
|
"\"one-byte+two-byte\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(crate::RTPBufferFlags, crate::RTPBufferFlags::all());
|
||||||
|
check_roundtrip!(crate::RTPBufferMapFlags, crate::RTPBufferMapFlags::all());
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::RTPHeaderExtensionDirection,
|
||||||
|
crate::RTPHeaderExtensionDirection::all()
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::RTPHeaderExtensionFlags,
|
||||||
|
crate::RTPHeaderExtensionFlags::all()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,9 @@ mod auto;
|
||||||
pub use crate::auto::functions::*;
|
pub use crate::auto::functions::*;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
pub mod subclass;
|
pub mod subclass;
|
||||||
|
|
||||||
pub mod rtp_buffer;
|
pub mod rtp_buffer;
|
||||||
|
|
|
@ -24,9 +24,11 @@ gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
||||||
gst-rtsp = { package = "gstreamer-rtsp", path = "../gstreamer-rtsp" }
|
gst-rtsp = { package = "gstreamer-rtsp", path = "../gstreamer-rtsp" }
|
||||||
gst-net = { package = "gstreamer-net", path = "../gstreamer-net" }
|
gst-net = { package = "gstreamer-net", path = "../gstreamer-net" }
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -34,7 +36,8 @@ v1_16 = ["gst/v1_16", "gst-sdp/v1_16", "gst-rtsp/v1_16", "gst-net/v1_16", "ffi/v
|
||||||
v1_18 = ["gst/v1_18", "gst-sdp/v1_18", "gst-rtsp/v1_18", "gst-net/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-sdp/v1_18", "gst-rtsp/v1_18", "gst-net/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-sdp/v1_20", "gst-rtsp/v1_20", "gst-net/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-sdp/v1_20", "gst-rtsp/v1_20", "gst-net/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "gst-sdp/v1_22", "gst-rtsp/v1_22", "gst-net/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "gst-sdp/v1_22", "gst-rtsp/v1_22", "gst-net/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gio/dox", "gst/dox", "gst-sdp/dox", "gst-rtsp/dox", "gst-net/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gio/dox", "gst/dox", "gst-sdp/dox", "gst-rtsp/dox", "gst-net/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de", "gst-rtsp/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
57
gstreamer-rtsp-server/src/flag_serde.rs
Normal file
57
gstreamer-rtsp-server/src/flag_serde.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::RTSPTransportMode);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::RTSPTransportMode::all(), "\"play+record\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTSPTransportMode,
|
||||||
|
crate::RTSPTransportMode::all(),
|
||||||
|
"\"play+record\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(crate::RTSPTransportMode, crate::RTSPTransportMode::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,9 @@ macro_rules! skip_assert_initialized {
|
||||||
mod auto;
|
mod auto;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
mod rtsp_address_pool;
|
mod rtsp_address_pool;
|
||||||
mod rtsp_auth;
|
mod rtsp_auth;
|
||||||
mod rtsp_client;
|
mod rtsp_client;
|
||||||
|
|
|
@ -20,9 +20,11 @@ ffi = { package = "gstreamer-rtsp-sys", path = "sys" }
|
||||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||||
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
gst-sdp = { package = "gstreamer-sdp", path = "../gstreamer-sdp" }
|
||||||
|
serde = { version = "1.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gir-format-check = "0.1"
|
gir-format-check = "0.1"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -30,7 +32,8 @@ v1_16 = ["gst/v1_16", "gst-sdp/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "gst-sdp/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-sdp/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-sdp/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-sdp/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "gst-sdp/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "gst-sdp/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-sdp/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-sdp/dox", "ser_de"]
|
||||||
|
ser_de = ["serde", "gst/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
97
gstreamer-rtsp/src/flag_serde.rs
Normal file
97
gstreamer-rtsp/src/flag_serde.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::RTSPEvent);
|
||||||
|
bitflags_serde_impl!(crate::RTSPLowerTrans);
|
||||||
|
bitflags_serde_impl!(crate::RTSPMethod);
|
||||||
|
bitflags_serde_impl!(crate::RTSPProfile);
|
||||||
|
bitflags_serde_impl!(crate::RTSPTransMode);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::RTSPEvent::all(), "\"read+write\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::RTSPLowerTrans::all(),
|
||||||
|
"\"udp+udp-mcast+tcp+http+tls\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::RTSPMethod::all(),
|
||||||
|
concat!(
|
||||||
|
"\"describe+announce+get-parameter+options+pause+play+record",
|
||||||
|
"+redirect+setup+set-parameter+teardown+get+post\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(crate::RTSPProfile::all(), "\"avp+savp+avpf+savpf\"");
|
||||||
|
check_serialize!(crate::RTSPTransMode::all(), "\"rtp+rdt\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(crate::RTSPEvent, crate::RTSPEvent::all(), "\"read+write\"");
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTSPLowerTrans,
|
||||||
|
crate::RTSPLowerTrans::all(),
|
||||||
|
"\"udp+udp-mcast+tcp+http+tls\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTSPMethod,
|
||||||
|
crate::RTSPMethod::all(),
|
||||||
|
concat!(
|
||||||
|
"\"describe+announce+get-parameter+options+pause+play+record",
|
||||||
|
"+redirect+setup+set-parameter+teardown+get+post\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTSPProfile,
|
||||||
|
crate::RTSPProfile::all(),
|
||||||
|
"\"avp+savp+avpf+savpf\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::RTSPTransMode,
|
||||||
|
crate::RTSPTransMode::all(),
|
||||||
|
"\"rtp+rdt\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(crate::RTSPEvent, crate::RTSPEvent::all());
|
||||||
|
check_roundtrip!(crate::RTSPLowerTrans, crate::RTSPLowerTrans::all());
|
||||||
|
check_roundtrip!(crate::RTSPMethod, crate::RTSPMethod::all());
|
||||||
|
check_roundtrip!(crate::RTSPProfile, crate::RTSPProfile::all());
|
||||||
|
check_roundtrip!(crate::RTSPTransMode, crate::RTSPTransMode::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,9 @@ macro_rules! skip_assert_initialized {
|
||||||
mod auto;
|
mod auto;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
// Re-export all the traits in a prelude module, so that applications
|
// Re-export all the traits in a prelude module, so that applications
|
||||||
// can always "use gst_rtsp::prelude::*" without getting conflicts
|
// can always "use gst_rtsp::prelude::*" without getting conflicts
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
|
|
@ -36,8 +36,8 @@ v1_16 = ["gst/v1_16", "gst-base/v1_16", "ffi/v1_16"]
|
||||||
v1_18 = ["gst/v1_18", "gst-base/v1_18", "ffi/v1_18", "v1_16"]
|
v1_18 = ["gst/v1_18", "gst-base/v1_18", "ffi/v1_18", "v1_16"]
|
||||||
v1_20 = ["gst/v1_20", "gst-base/v1_20", "ffi/v1_20", "v1_18"]
|
v1_20 = ["gst/v1_20", "gst-base/v1_20", "ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["gst/v1_22", "gst-base/v1_22", "ffi/v1_22", "v1_20"]
|
v1_22 = ["gst/v1_22", "gst-base/v1_22", "ffi/v1_22", "v1_20"]
|
||||||
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox"]
|
dox = ["v1_22", "ffi/dox", "glib/dox", "gst/dox", "gst-base/dox", "ser_de"]
|
||||||
ser_de = ["serde"]
|
ser_de = ["serde", "gst/ser_de"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
features = ["dox"]
|
features = ["dox"]
|
||||||
|
|
231
gstreamer-video/src/flag_serde.rs
Normal file
231
gstreamer-video/src/flag_serde.rs
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
use gst::bitflags_serde_impl;
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::NavigationModifierType, "v1_22");
|
||||||
|
bitflags_serde_impl!(crate::VideoBufferFlags);
|
||||||
|
bitflags_serde_impl!(crate::VideoChromaSite);
|
||||||
|
bitflags_serde_impl!(crate::VideoCodecFrameFlags, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::VideoDecoderRequestSyncPointFlags, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::VideoFlags);
|
||||||
|
bitflags_serde_impl!(crate::VideoFormatFlags);
|
||||||
|
bitflags_serde_impl!(crate::VideoFrameFlags);
|
||||||
|
bitflags_serde_impl!(crate::VideoMultiviewFlags);
|
||||||
|
bitflags_serde_impl!(crate::VideoOverlayFormatFlags, "v1_16");
|
||||||
|
bitflags_serde_impl!(crate::VideoPackFlags);
|
||||||
|
bitflags_serde_impl!(crate::VideoTimeCodeFlags, "v1_18");
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "v1_22")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::NavigationModifierType::all(),
|
||||||
|
concat!(
|
||||||
|
"\"shift-mask+lock-mask+control-mask+alt-mask+button1-mask",
|
||||||
|
"+button2-mask+button3-mask+button4-mask+button5-mask",
|
||||||
|
"+super-mask+hyper-mask+meta-mask\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoBufferFlags::all(),
|
||||||
|
"\"interlaced+tff+rff+onefield+multiple-view+first-in-bundle+marker\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoChromaSite::all(),
|
||||||
|
"\"none+h-cosited+v-cosited+alt-line\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoCodecFrameFlags::all(),
|
||||||
|
"\"decode-only+sync-point+force-keyframe+force-keyframe-headers+corrupted\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoDecoderRequestSyncPointFlags::all(),
|
||||||
|
"\"discard-input+corrupt-output\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoFlags::all(),
|
||||||
|
"\"variable-fps+premultiplied-alpha\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_22")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoFormatFlags::all(),
|
||||||
|
"\"yuv+rgb+gray+alpha+le+palette+complex+unpack+tiled+subtiles\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoFrameFlags::all(),
|
||||||
|
"\"interlaced+tff+rff+onefield+multiple-view+first-in-bundle\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoMultiviewFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"right-view-first+left-flipped+left-flopped+right-flipped",
|
||||||
|
"+right-flopped+half-aspect+mixed-mono\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_16")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoOverlayFormatFlags::all(),
|
||||||
|
"\"premultiplied-alpha+global-alpha\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoPackFlags::all(),
|
||||||
|
"\"truncate-range+interlaced\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::VideoTimeCodeFlags::all(),
|
||||||
|
"\"drop-frame+interlaced\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "v1_22")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::NavigationModifierType,
|
||||||
|
crate::NavigationModifierType::all(),
|
||||||
|
concat!(
|
||||||
|
"\"shift-mask+lock-mask+control-mask+alt-mask+button1-mask",
|
||||||
|
"+button2-mask+button3-mask+button4-mask+button5-mask",
|
||||||
|
"+super-mask+hyper-mask+meta-mask\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoBufferFlags,
|
||||||
|
crate::VideoBufferFlags::all(),
|
||||||
|
"\"interlaced+tff+rff+onefield+multiple-view+first-in-bundle+marker\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoChromaSite,
|
||||||
|
crate::VideoChromaSite::all(),
|
||||||
|
"\"none+h-cosited+v-cosited+alt-line\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoCodecFrameFlags,
|
||||||
|
crate::VideoCodecFrameFlags::all(),
|
||||||
|
"\"decode-only+sync-point+force-keyframe+force-keyframe-headers+corrupted\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoDecoderRequestSyncPointFlags,
|
||||||
|
crate::VideoDecoderRequestSyncPointFlags::all(),
|
||||||
|
"\"discard-input+corrupt-output\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoFlags,
|
||||||
|
crate::VideoFlags::all(),
|
||||||
|
"\"variable-fps+premultiplied-alpha\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_22")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoFormatFlags,
|
||||||
|
crate::VideoFormatFlags::all(),
|
||||||
|
"\"yuv+rgb+gray+alpha+le+palette+complex+unpack+tiled+subtiles\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoFrameFlags,
|
||||||
|
crate::VideoFrameFlags::all(),
|
||||||
|
"\"interlaced+tff+rff+onefield+multiple-view+first-in-bundle\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoMultiviewFlags,
|
||||||
|
crate::VideoMultiviewFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"right-view-first+left-flipped+left-flopped+right-flipped",
|
||||||
|
"+right-flopped+half-aspect+mixed-mono\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_16")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoOverlayFormatFlags,
|
||||||
|
crate::VideoOverlayFormatFlags::all(),
|
||||||
|
"\"premultiplied-alpha+global-alpha\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoPackFlags,
|
||||||
|
crate::VideoPackFlags::all(),
|
||||||
|
"\"truncate-range+interlaced\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::VideoTimeCodeFlags,
|
||||||
|
crate::VideoTimeCodeFlags::all(),
|
||||||
|
"\"drop-frame+interlaced\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "v1_22")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::NavigationModifierType,
|
||||||
|
crate::NavigationModifierType::all()
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_roundtrip!(crate::VideoBufferFlags, crate::VideoBufferFlags::all());
|
||||||
|
check_roundtrip!(crate::VideoChromaSite, crate::VideoChromaSite::all());
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::VideoCodecFrameFlags,
|
||||||
|
crate::VideoCodecFrameFlags::all()
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::VideoDecoderRequestSyncPointFlags,
|
||||||
|
crate::VideoDecoderRequestSyncPointFlags::all()
|
||||||
|
);
|
||||||
|
check_roundtrip!(crate::VideoFlags, crate::VideoFlags::all());
|
||||||
|
#[cfg(feature = "v1_22")]
|
||||||
|
check_roundtrip!(crate::VideoFormatFlags, crate::VideoFormatFlags::all());
|
||||||
|
check_roundtrip!(crate::VideoFrameFlags, crate::VideoFrameFlags::all());
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::VideoMultiviewFlags,
|
||||||
|
crate::VideoMultiviewFlags::all()
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_16")]
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::VideoOverlayFormatFlags,
|
||||||
|
crate::VideoOverlayFormatFlags::all()
|
||||||
|
);
|
||||||
|
check_roundtrip!(crate::VideoPackFlags, crate::VideoPackFlags::all());
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_roundtrip!(crate::VideoTimeCodeFlags, crate::VideoTimeCodeFlags::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,9 @@ macro_rules! skip_assert_initialized {
|
||||||
mod auto;
|
mod auto;
|
||||||
pub use crate::auto::*;
|
pub use crate::auto::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
mod navigation;
|
mod navigation;
|
||||||
|
|
||||||
mod caps_features;
|
mod caps_features;
|
||||||
|
|
|
@ -9,10 +9,6 @@ use std::mem;
|
||||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
|
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
|
||||||
use crate::NavigationModifierType;
|
use crate::NavigationModifierType;
|
||||||
|
|
||||||
#[cfg(all(feature = "ser_de", any(feature = "v1_22", feature = "dox")))]
|
|
||||||
#[cfg_attr(feature = "dox", feature = "ser_de", doc(cfg(feature = "v1_22")))]
|
|
||||||
use glib::{FlagsClass, StaticType};
|
|
||||||
|
|
||||||
// FIXME: Copy from gstreamer/src/event.rs
|
// FIXME: Copy from gstreamer/src/event.rs
|
||||||
macro_rules! event_builder_generic_impl {
|
macro_rules! event_builder_generic_impl {
|
||||||
($new_fn:expr) => {
|
($new_fn:expr) => {
|
||||||
|
@ -1267,81 +1263,6 @@ impl NavigationEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "ser_de", any(feature = "v1_22", feature = "dox")))]
|
|
||||||
#[cfg_attr(feature = "dox", feature = "ser_de", doc(cfg(feature = "v1_22")))]
|
|
||||||
impl serde::Serialize for NavigationModifierType {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: serde::Serializer,
|
|
||||||
{
|
|
||||||
let class = FlagsClass::new(NavigationModifierType::static_type()).unwrap();
|
|
||||||
|
|
||||||
let mut handled = NavigationModifierType::empty();
|
|
||||||
let mut res = "".to_owned();
|
|
||||||
for v in class.values() {
|
|
||||||
let value = v.value();
|
|
||||||
if value.count_ones() != 1 || value & handled.bits() != 0 {
|
|
||||||
continue;
|
|
||||||
} else if (value & self.bits()) == value {
|
|
||||||
if !res.is_empty() {
|
|
||||||
res.push('+');
|
|
||||||
}
|
|
||||||
res.push_str(v.nick());
|
|
||||||
handled.insert(NavigationModifierType::from_bits(value).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer.serialize_str(&res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(feature = "ser_de", any(feature = "v1_22", feature = "dox")))]
|
|
||||||
#[cfg_attr(feature = "dox", feature = "ser_de", doc(cfg(feature = "v1_22")))]
|
|
||||||
struct NavigationModifierTypeVisitor;
|
|
||||||
|
|
||||||
#[cfg(all(feature = "ser_de", any(feature = "v1_22", feature = "dox")))]
|
|
||||||
#[cfg_attr(feature = "dox", feature = "ser_de", doc(cfg(feature = "v1_22")))]
|
|
||||||
impl<'de> serde::de::Visitor<'de> for NavigationModifierTypeVisitor {
|
|
||||||
type Value = NavigationModifierType;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
formatter.write_str("one or more mask names separated by plus signs, or the empty string")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E: serde::de::Error>(self, value: &str) -> std::result::Result<Self::Value, E> {
|
|
||||||
if value.is_empty() {
|
|
||||||
return Ok(NavigationModifierType::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut gvalue = glib::Value::from_type(NavigationModifierType::static_type());
|
|
||||||
let tokens = value.split('+');
|
|
||||||
let class = FlagsClass::new(NavigationModifierType::static_type()).unwrap();
|
|
||||||
|
|
||||||
for token in tokens {
|
|
||||||
gvalue = class
|
|
||||||
.set_by_nick(gvalue, token)
|
|
||||||
.map_err(|_| serde::de::Error::custom(&format!("Invalid value: {}", token)))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(unsafe {
|
|
||||||
from_glib(glib::gobject_ffi::g_value_get_flags(
|
|
||||||
gvalue.to_glib_none().0,
|
|
||||||
))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(feature = "ser_de", any(feature = "v1_22", feature = "dox")))]
|
|
||||||
#[cfg_attr(feature = "dox", feature = "ser_de", doc(cfg(feature = "v1_22")))]
|
|
||||||
impl<'de> serde::Deserialize<'de> for NavigationModifierType {
|
|
||||||
fn deserialize<D: serde::de::Deserializer<'de>>(
|
|
||||||
deserializer: D,
|
|
||||||
) -> std::result::Result<Self, D::Error> {
|
|
||||||
skip_assert_initialized!();
|
|
||||||
deserializer.deserialize_str(NavigationModifierTypeVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -104,9 +104,7 @@ mod tests {
|
||||||
" duration: Some(5),",
|
" duration: Some(5),",
|
||||||
" offset: 3,",
|
" offset: 3,",
|
||||||
" offset_end: 4,",
|
" offset_end: 4,",
|
||||||
" flags: (",
|
" flags: \"live+discont\",",
|
||||||
" bits: 80,",
|
|
||||||
" ),",
|
|
||||||
" buffer: \"AQIDBA==\",",
|
" buffer: \"AQIDBA==\",",
|
||||||
")"
|
")"
|
||||||
)
|
)
|
||||||
|
@ -123,7 +121,7 @@ mod tests {
|
||||||
"\"duration\":5,",
|
"\"duration\":5,",
|
||||||
"\"offset\":3,",
|
"\"offset\":3,",
|
||||||
"\"offset_end\":4,",
|
"\"offset_end\":4,",
|
||||||
"\"flags\":{\"bits\":80},",
|
"\"flags\":\"live+discont\",",
|
||||||
"\"buffer\":[1,2,3,4]",
|
"\"buffer\":[1,2,3,4]",
|
||||||
"}"
|
"}"
|
||||||
)
|
)
|
||||||
|
@ -143,9 +141,7 @@ mod tests {
|
||||||
duration: Some(5),
|
duration: Some(5),
|
||||||
offset: 3,
|
offset: 3,
|
||||||
offset_end: 4,
|
offset_end: 4,
|
||||||
flags: (
|
flags: "live+discont",
|
||||||
bits: 80,
|
|
||||||
),
|
|
||||||
buffer: "AQIDBA==",
|
buffer: "AQIDBA==",
|
||||||
)
|
)
|
||||||
"#;
|
"#;
|
||||||
|
@ -168,7 +164,7 @@ mod tests {
|
||||||
"duration":5,
|
"duration":5,
|
||||||
"offset":3,
|
"offset":3,
|
||||||
"offset_end":4,
|
"offset_end":4,
|
||||||
"flags":{"bits":80},
|
"flags":"live+discont",
|
||||||
"buffer":[1,2,3,4]
|
"buffer":[1,2,3,4]
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
|
@ -107,9 +107,7 @@ mod tests {
|
||||||
" duration: Some(4),",
|
" duration: Some(4),",
|
||||||
" offset: 0,",
|
" offset: 0,",
|
||||||
" offset_end: 4,",
|
" offset_end: 4,",
|
||||||
" flags: (",
|
" flags: \"\",",
|
||||||
" bits: 0,",
|
|
||||||
" ),",
|
|
||||||
" buffer: \"AQIDBA==\",",
|
" buffer: \"AQIDBA==\",",
|
||||||
" ),",
|
" ),",
|
||||||
" (",
|
" (",
|
||||||
|
@ -118,9 +116,7 @@ mod tests {
|
||||||
" duration: Some(2),",
|
" duration: Some(2),",
|
||||||
" offset: 4,",
|
" offset: 4,",
|
||||||
" offset_end: 6,",
|
" offset_end: 6,",
|
||||||
" flags: (",
|
" flags: \"\",",
|
||||||
" bits: 0,",
|
|
||||||
" ),",
|
|
||||||
" buffer: \"BQY=\",",
|
" buffer: \"BQY=\",",
|
||||||
" ),",
|
" ),",
|
||||||
"]"
|
"]"
|
||||||
|
@ -142,9 +138,7 @@ mod tests {
|
||||||
duration: Some(4),
|
duration: Some(4),
|
||||||
offset: 0,
|
offset: 0,
|
||||||
offset_end: 4,
|
offset_end: 4,
|
||||||
flags: (
|
flags: "",
|
||||||
bits: 0,
|
|
||||||
),
|
|
||||||
buffer: "AQIDBA==",
|
buffer: "AQIDBA==",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
@ -153,9 +147,7 @@ mod tests {
|
||||||
duration: Some(2),
|
duration: Some(2),
|
||||||
offset: 4,
|
offset: 4,
|
||||||
offset_end: 6,
|
offset_end: 6,
|
||||||
flags: (
|
flags: "",
|
||||||
bits: 0,
|
|
||||||
),
|
|
||||||
buffer: "BQY=",
|
buffer: "BQY=",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
533
gstreamer/src/flag_serde.rs
Normal file
533
gstreamer/src/flag_serde.rs
Normal file
|
@ -0,0 +1,533 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
use glib::translate::{from_glib, ToGlibPtr};
|
||||||
|
use glib::{FlagsClass, StaticType, ToValue};
|
||||||
|
|
||||||
|
bitflags_serde_impl!(crate::BinFlags);
|
||||||
|
bitflags_serde_impl!(crate::BufferCopyFlags);
|
||||||
|
bitflags_serde_impl!(crate::BufferFlags);
|
||||||
|
bitflags_serde_impl!(crate::BufferPoolAcquireFlags);
|
||||||
|
bitflags_serde_impl!(crate::ClockFlags);
|
||||||
|
|
||||||
|
impl serde::Serialize for crate::DebugColorFlags {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&format!(
|
||||||
|
"{}+{}{}{}",
|
||||||
|
match *self & Self::from_bits(0b111).expect("Failed to create value from fg-color mask")
|
||||||
|
{
|
||||||
|
Self::FG_BLACK => "fg-black",
|
||||||
|
Self::FG_RED => "fg-red",
|
||||||
|
Self::FG_GREEN => "fg-green",
|
||||||
|
Self::FG_YELLOW => "fg-yellow",
|
||||||
|
Self::FG_BLUE => "fg-blue",
|
||||||
|
Self::FG_MAGENTA => "fg-magenta",
|
||||||
|
Self::FG_CYAN => "fg-cyan",
|
||||||
|
Self::FG_WHITE => "fg-white",
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
match *self
|
||||||
|
& Self::from_bits(0b111_0000).expect("Failed to create value from bg-color mask")
|
||||||
|
{
|
||||||
|
Self::BG_BLACK => "bg-black",
|
||||||
|
Self::BG_RED => "bg-red",
|
||||||
|
Self::BG_GREEN => "bg-green",
|
||||||
|
Self::BG_YELLOW => "bg-yellow",
|
||||||
|
Self::BG_BLUE => "bg-blue",
|
||||||
|
Self::BG_MAGENTA => "bg-magenta",
|
||||||
|
Self::BG_CYAN => "bg-cyan",
|
||||||
|
Self::BG_WHITE => "bg-white",
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
if self.contains(Self::BOLD) {
|
||||||
|
"+bold"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
},
|
||||||
|
if self.contains(Self::UNDERLINE) {
|
||||||
|
"+underline"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags_deserialize_impl!(crate::DebugColorFlags);
|
||||||
|
bitflags_serialize_impl!(crate::DebugGraphDetails, by_ones_decreasing);
|
||||||
|
bitflags_deserialize_impl!(crate::DebugGraphDetails);
|
||||||
|
bitflags_serde_impl!(crate::ElementFlags);
|
||||||
|
bitflags_serde_impl!(crate::EventTypeFlags);
|
||||||
|
bitflags_serde_impl!(crate::GapFlags, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::MemoryFlags);
|
||||||
|
bitflags_serde_impl!(crate::MetaFlags);
|
||||||
|
bitflags_serde_impl!(crate::ObjectFlags);
|
||||||
|
bitflags_serde_impl!(crate::PadFlags);
|
||||||
|
bitflags_serde_impl!(crate::PadLinkCheck);
|
||||||
|
bitflags_serde_impl!(crate::PadProbeType);
|
||||||
|
bitflags_serde_impl!(crate::ParseFlags);
|
||||||
|
bitflags_serde_impl!(crate::PluginAPIFlags, "v1_18");
|
||||||
|
bitflags_serde_impl!(crate::PluginDependencyFlags);
|
||||||
|
bitflags_serde_impl!(crate::PluginFlags);
|
||||||
|
bitflags_serde_impl!(crate::SchedulingFlags);
|
||||||
|
bitflags_serde_impl!(crate::SeekFlags);
|
||||||
|
bitflags_serde_impl!(crate::SegmentFlags);
|
||||||
|
bitflags_serde_impl!(crate::SerializeFlags, "v1_20");
|
||||||
|
bitflags_serde_impl!(crate::StackTraceFlags);
|
||||||
|
bitflags_serde_impl!(crate::StreamFlags);
|
||||||
|
bitflags_serde_impl!(crate::StreamType);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
macro_rules! check_serialize {
|
||||||
|
($flags:expr, $expected:expr) => {
|
||||||
|
let actual = serde_json::to_string(&$flags).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_deserialize {
|
||||||
|
($ty:ty, $expected:expr, $json:expr) => {
|
||||||
|
let actual: $ty = serde_json::from_str(&$json).unwrap();
|
||||||
|
assert_eq!(actual, $expected);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! check_roundtrip {
|
||||||
|
($ty:ty, $flags:expr) => {
|
||||||
|
let json = serde_json::to_string(&$flags).unwrap();
|
||||||
|
let deserialized: $ty = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(deserialized, $flags);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize() {
|
||||||
|
crate::init().unwrap();
|
||||||
|
|
||||||
|
check_serialize!(crate::BinFlags::empty(), "\"\"");
|
||||||
|
check_serialize!(crate::BinFlags::all(), "\"no-resync+streams-aware\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::BufferCopyFlags::all(),
|
||||||
|
"\"flags+timestamps+meta+memory+merge+deep\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::BufferFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"live+decode-only+discont+resync+corrupted+marker+header+gap",
|
||||||
|
"+droppable+delta-unit+tag-memory+sync-after+non-droppable\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::BufferPoolAcquireFlags::all(),
|
||||||
|
"\"key-unit+dontwait+discont\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::ClockFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"can-do-single-sync+can-do-single-async",
|
||||||
|
"+can-do-periodic-sync+can-do-periodic-async",
|
||||||
|
"+can-set-resolution+can-set-master+needs-startup-sync\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
check_serialize!(
|
||||||
|
crate::DebugColorFlags::all(),
|
||||||
|
"\"fg-white+bg-white+bold+underline\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::DebugColorFlags::FG_MAGENTA | crate::DebugColorFlags::BOLD,
|
||||||
|
"\"fg-magenta+bg-black+bold\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::DebugColorFlags::FG_RED
|
||||||
|
| crate::DebugColorFlags::FG_BLUE
|
||||||
|
| crate::DebugColorFlags::BG_BLACK,
|
||||||
|
"\"fg-magenta+bg-black\""
|
||||||
|
);
|
||||||
|
|
||||||
|
check_serialize!(crate::DebugGraphDetails::all(), "\"verbose\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::DebugGraphDetails::MEDIA_TYPE
|
||||||
|
| crate::DebugGraphDetails::CAPS_DETAILS
|
||||||
|
| crate::DebugGraphDetails::NON_DEFAULT_PARAMS
|
||||||
|
| crate::DebugGraphDetails::STATES
|
||||||
|
| crate::DebugGraphDetails::FULL_PARAMS
|
||||||
|
| crate::DebugGraphDetails::ALL,
|
||||||
|
"\"all+full-params\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::DebugGraphDetails::MEDIA_TYPE
|
||||||
|
| crate::DebugGraphDetails::CAPS_DETAILS
|
||||||
|
| crate::DebugGraphDetails::NON_DEFAULT_PARAMS
|
||||||
|
| crate::DebugGraphDetails::STATES
|
||||||
|
| crate::DebugGraphDetails::FULL_PARAMS,
|
||||||
|
"\"all+full-params\""
|
||||||
|
);
|
||||||
|
|
||||||
|
check_serialize!(
|
||||||
|
crate::ElementFlags::all(),
|
||||||
|
"\"locked-state+sink+source+provide-clock+require-clock+indexable\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::EventTypeFlags::all(),
|
||||||
|
"\"upstream+downstream+serialized+sticky+sticky-multi\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(crate::GapFlags::all(), "\"data\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::MemoryFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"readonly+no-share+zero-prefixed+zero-padded",
|
||||||
|
"+physically-contiguous+not-mappable\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(crate::MetaFlags::all(), "\"readonly+pooled+locked\"");
|
||||||
|
check_serialize!(crate::ObjectFlags::all(), "\"may-be-leaked\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::PadFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"blocked+flushing+eos+blocking+need-parent+need-reconfigure",
|
||||||
|
"+pending-events+fixed-caps+proxy-caps+proxy-allocation",
|
||||||
|
"+proxy-scheduling+accept-intersect+accept-template\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::PadLinkCheck::all(),
|
||||||
|
"\"hierarchy+template-caps+caps+no-reconfigure\""
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::PadProbeType::all(),
|
||||||
|
concat!(
|
||||||
|
"\"idle+block+buffer+buffer-list+event-downstream",
|
||||||
|
"+event-upstream+event-flush+query-downstream+query-upstream",
|
||||||
|
"+push+pull\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(
|
||||||
|
crate::ParseFlags::all(),
|
||||||
|
"\"fatal-errors+no-single-element-bins+place-in-bin\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_serialize!(crate::PluginAPIFlags::all(), "\"members\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::PluginDependencyFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"recurse+paths-are-default-only+file-name-is-suffix",
|
||||||
|
"+file-name-is-prefix+paths-are-relative-to-exe\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_serialize!(crate::PluginFlags::all(), "\"cached+blacklisted\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::SchedulingFlags::all(),
|
||||||
|
"\"seekable+sequential+bandwidth-limited\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::SeekFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"flush+accurate+key-unit+segment+trickmode+snap-before",
|
||||||
|
"+snap-after+trickmode-key-units+trickmode-no-audio",
|
||||||
|
"+trickmode-forward-predicted+instant-rate-change\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_serialize!(
|
||||||
|
crate::SegmentFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"reset+trickmode+segment+trickmode-key-units",
|
||||||
|
"+trickmode-forward-predicted+trickmode-no-audio\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_serialize!(crate::SerializeFlags::all(), "\"backward-compat\"");
|
||||||
|
check_serialize!(crate::StackTraceFlags::all(), "\"full\"");
|
||||||
|
check_serialize!(crate::StreamFlags::all(), "\"sparse+select+unselect\"");
|
||||||
|
check_serialize!(
|
||||||
|
crate::StreamType::all(),
|
||||||
|
"\"unknown+audio+video+container+text\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialize() {
|
||||||
|
crate::init().unwrap();
|
||||||
|
|
||||||
|
check_deserialize!(crate::BinFlags, crate::BinFlags::empty(), "\"\"");
|
||||||
|
check_deserialize!(
|
||||||
|
crate::BinFlags,
|
||||||
|
crate::BinFlags::all(),
|
||||||
|
"\"no-resync+streams-aware\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::BufferCopyFlags,
|
||||||
|
crate::BufferCopyFlags::all(),
|
||||||
|
"\"flags+timestamps+meta+memory+merge+deep\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::BufferFlags,
|
||||||
|
crate::BufferFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"live+decode-only+discont+resync+corrupted+marker+header+gap",
|
||||||
|
"+droppable+delta-unit+tag-memory+sync-after+non-droppable\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::BufferPoolAcquireFlags,
|
||||||
|
crate::BufferPoolAcquireFlags::all(),
|
||||||
|
"\"key-unit+dontwait+discont\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::ClockFlags,
|
||||||
|
crate::ClockFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"can-do-single-sync+can-do-single-async",
|
||||||
|
"+can-do-periodic-sync+can-do-periodic-async",
|
||||||
|
"+can-set-resolution+can-set-master+needs-startup-sync\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DebugColorFlags,
|
||||||
|
crate::DebugColorFlags::all(),
|
||||||
|
"\"fg-white+bg-white+bold+underline\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DebugColorFlags,
|
||||||
|
crate::DebugColorFlags::FG_MAGENTA | crate::DebugColorFlags::BOLD,
|
||||||
|
"\"fg-magenta+bg-black+bold\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DebugColorFlags,
|
||||||
|
crate::DebugColorFlags::FG_RED
|
||||||
|
| crate::DebugColorFlags::FG_BLUE
|
||||||
|
| crate::DebugColorFlags::BG_BLACK,
|
||||||
|
"\"fg-magenta+bg-black\""
|
||||||
|
);
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DebugGraphDetails,
|
||||||
|
crate::DebugGraphDetails::all(),
|
||||||
|
"\"verbose\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DebugGraphDetails,
|
||||||
|
crate::DebugGraphDetails::MEDIA_TYPE
|
||||||
|
| crate::DebugGraphDetails::CAPS_DETAILS
|
||||||
|
| crate::DebugGraphDetails::NON_DEFAULT_PARAMS
|
||||||
|
| crate::DebugGraphDetails::STATES
|
||||||
|
| crate::DebugGraphDetails::FULL_PARAMS
|
||||||
|
| crate::DebugGraphDetails::ALL,
|
||||||
|
"\"all+full-params\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::DebugGraphDetails,
|
||||||
|
crate::DebugGraphDetails::MEDIA_TYPE
|
||||||
|
| crate::DebugGraphDetails::CAPS_DETAILS
|
||||||
|
| crate::DebugGraphDetails::NON_DEFAULT_PARAMS
|
||||||
|
| crate::DebugGraphDetails::STATES
|
||||||
|
| crate::DebugGraphDetails::FULL_PARAMS,
|
||||||
|
"\"all+full-params\""
|
||||||
|
);
|
||||||
|
|
||||||
|
check_deserialize!(
|
||||||
|
crate::ElementFlags,
|
||||||
|
crate::ElementFlags::all(),
|
||||||
|
"\"locked-state+sink+source+provide-clock+require-clock+indexable\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::EventTypeFlags,
|
||||||
|
crate::EventTypeFlags::all(),
|
||||||
|
"\"upstream+downstream+serialized+sticky+sticky-multi\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(crate::GapFlags, crate::GapFlags::all(), "\"data\"");
|
||||||
|
check_deserialize!(
|
||||||
|
crate::MemoryFlags,
|
||||||
|
crate::MemoryFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"readonly+no-share+zero-prefixed+zero-padded",
|
||||||
|
"+physically-contiguous+not-mappable\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::MetaFlags,
|
||||||
|
crate::MetaFlags::all(),
|
||||||
|
"\"readonly+pooled+locked\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::ObjectFlags,
|
||||||
|
crate::ObjectFlags::all(),
|
||||||
|
"\"may-be-leaked\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PadFlags,
|
||||||
|
crate::PadFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"blocked+flushing+eos+blocking+need-parent+need-reconfigure",
|
||||||
|
"+pending-events+fixed-caps+proxy-caps+proxy-allocation",
|
||||||
|
"+proxy-scheduling+accept-intersect+accept-template\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PadLinkCheck,
|
||||||
|
crate::PadLinkCheck::all(),
|
||||||
|
"\"hierarchy+template-caps+caps+no-reconfigure\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PadProbeType,
|
||||||
|
crate::PadProbeType::all(),
|
||||||
|
concat!(
|
||||||
|
"\"idle+block+buffer+buffer-list+event-downstream",
|
||||||
|
"+event-upstream+event-flush+query-downstream+query-upstream",
|
||||||
|
"+push+pull\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::ParseFlags,
|
||||||
|
crate::ParseFlags::all(),
|
||||||
|
"\"fatal-errors+no-single-element-bins+place-in-bin\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PluginAPIFlags,
|
||||||
|
crate::PluginAPIFlags::all(),
|
||||||
|
"\"members\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PluginDependencyFlags,
|
||||||
|
crate::PluginDependencyFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"recurse+paths-are-default-only+file-name-is-suffix",
|
||||||
|
"+file-name-is-prefix+paths-are-relative-to-exe\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::PluginFlags,
|
||||||
|
crate::PluginFlags::all(),
|
||||||
|
"\"cached+blacklisted\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::SchedulingFlags,
|
||||||
|
crate::SchedulingFlags::all(),
|
||||||
|
"\"seekable+sequential+bandwidth-limited\""
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::SeekFlags,
|
||||||
|
crate::SeekFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"flush+accurate+key-unit+segment+trickmode+snap-before",
|
||||||
|
"+snap-after+trickmode-key-units+trickmode-no-audio",
|
||||||
|
"+trickmode-forward-predicted+instant-rate-change\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::SegmentFlags,
|
||||||
|
crate::SegmentFlags::all(),
|
||||||
|
concat!(
|
||||||
|
"\"reset+trickmode+segment+trickmode-key-units",
|
||||||
|
"+trickmode-forward-predicted+trickmode-no-audio\""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_deserialize!(
|
||||||
|
crate::SerializeFlags,
|
||||||
|
crate::SerializeFlags::all(),
|
||||||
|
"\"backward-compat\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::StackTraceFlags,
|
||||||
|
crate::StackTraceFlags::all(),
|
||||||
|
"\"full\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::StreamFlags,
|
||||||
|
crate::StreamFlags::all(),
|
||||||
|
"\"sparse+select+unselect\""
|
||||||
|
);
|
||||||
|
check_deserialize!(
|
||||||
|
crate::StreamType,
|
||||||
|
crate::StreamType::all(),
|
||||||
|
"\"unknown+audio+video+container+text\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serde_roundtrip() {
|
||||||
|
crate::init().unwrap();
|
||||||
|
|
||||||
|
check_roundtrip!(crate::BinFlags, crate::BinFlags::empty());
|
||||||
|
check_roundtrip!(crate::BinFlags, crate::BinFlags::all());
|
||||||
|
check_roundtrip!(crate::BufferCopyFlags, crate::BufferCopyFlags::all());
|
||||||
|
check_roundtrip!(crate::BufferFlags, crate::BufferFlags::all());
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::BufferPoolAcquireFlags,
|
||||||
|
crate::BufferPoolAcquireFlags::all()
|
||||||
|
);
|
||||||
|
check_roundtrip!(crate::ClockFlags, crate::ClockFlags::all());
|
||||||
|
|
||||||
|
check_roundtrip!(crate::DebugColorFlags, crate::DebugColorFlags::all());
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::DebugColorFlags,
|
||||||
|
crate::DebugColorFlags::FG_MAGENTA | crate::DebugColorFlags::BOLD
|
||||||
|
);
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::DebugColorFlags,
|
||||||
|
crate::DebugColorFlags::FG_RED
|
||||||
|
| crate::DebugColorFlags::FG_BLUE
|
||||||
|
| crate::DebugColorFlags::BG_BLACK
|
||||||
|
);
|
||||||
|
|
||||||
|
check_roundtrip!(crate::DebugGraphDetails, crate::DebugGraphDetails::all());
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::DebugGraphDetails,
|
||||||
|
crate::DebugGraphDetails::MEDIA_TYPE
|
||||||
|
| crate::DebugGraphDetails::CAPS_DETAILS
|
||||||
|
| crate::DebugGraphDetails::NON_DEFAULT_PARAMS
|
||||||
|
| crate::DebugGraphDetails::STATES
|
||||||
|
| crate::DebugGraphDetails::FULL_PARAMS
|
||||||
|
| crate::DebugGraphDetails::ALL
|
||||||
|
);
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::DebugGraphDetails,
|
||||||
|
crate::DebugGraphDetails::MEDIA_TYPE
|
||||||
|
| crate::DebugGraphDetails::CAPS_DETAILS
|
||||||
|
| crate::DebugGraphDetails::NON_DEFAULT_PARAMS
|
||||||
|
| crate::DebugGraphDetails::STATES
|
||||||
|
| crate::DebugGraphDetails::FULL_PARAMS
|
||||||
|
);
|
||||||
|
|
||||||
|
check_roundtrip!(crate::ElementFlags, crate::ElementFlags::all());
|
||||||
|
check_roundtrip!(crate::EventTypeFlags, crate::EventTypeFlags::all());
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(crate::GapFlags, crate::GapFlags::all());
|
||||||
|
check_roundtrip!(crate::MemoryFlags, crate::MemoryFlags::all());
|
||||||
|
check_roundtrip!(crate::MetaFlags, crate::MetaFlags::all());
|
||||||
|
check_roundtrip!(crate::ObjectFlags, crate::ObjectFlags::all());
|
||||||
|
check_roundtrip!(crate::PadFlags, crate::PadFlags::all());
|
||||||
|
check_roundtrip!(crate::PadLinkCheck, crate::PadLinkCheck::all());
|
||||||
|
check_roundtrip!(crate::PadProbeType, crate::PadProbeType::all());
|
||||||
|
check_roundtrip!(crate::ParseFlags, crate::ParseFlags::all());
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_roundtrip!(crate::PluginAPIFlags, crate::PluginAPIFlags::all());
|
||||||
|
check_roundtrip!(
|
||||||
|
crate::PluginDependencyFlags,
|
||||||
|
crate::PluginDependencyFlags::all()
|
||||||
|
);
|
||||||
|
check_roundtrip!(crate::PluginFlags, crate::PluginFlags::all());
|
||||||
|
check_roundtrip!(crate::SchedulingFlags, crate::SchedulingFlags::all());
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_roundtrip!(crate::SeekFlags, crate::SeekFlags::all());
|
||||||
|
#[cfg(feature = "v1_18")]
|
||||||
|
check_roundtrip!(crate::SegmentFlags, crate::SegmentFlags::all());
|
||||||
|
#[cfg(feature = "v1_20")]
|
||||||
|
check_roundtrip!(crate::SerializeFlags, crate::SerializeFlags::all());
|
||||||
|
check_roundtrip!(crate::StackTraceFlags, crate::StackTraceFlags::all());
|
||||||
|
check_roundtrip!(crate::StreamFlags, crate::StreamFlags::all());
|
||||||
|
check_roundtrip!(crate::StreamType, crate::StreamType::all());
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,12 @@ pub use crate::auto::*;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod serde_macros;
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
pub use crate::serde_macros::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod log;
|
mod log;
|
||||||
pub use crate::log::*;
|
pub use crate::log::*;
|
||||||
|
@ -62,6 +68,9 @@ pub use crate::value::{
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod value_serde;
|
mod value_serde;
|
||||||
|
|
||||||
|
#[cfg(feature = "ser_de")]
|
||||||
|
mod flag_serde;
|
||||||
|
|
||||||
pub mod structure;
|
pub mod structure;
|
||||||
pub use crate::structure::{Structure, StructureRef};
|
pub use crate::structure::{Structure, StructureRef};
|
||||||
#[cfg(feature = "ser_de")]
|
#[cfg(feature = "ser_de")]
|
||||||
|
|
|
@ -142,9 +142,7 @@ mod tests {
|
||||||
" duration: Some(4),",
|
" duration: Some(4),",
|
||||||
" offset: 0,",
|
" offset: 0,",
|
||||||
" offset_end: 4,",
|
" offset_end: 4,",
|
||||||
" flags: (",
|
" flags: \"\",",
|
||||||
" bits: 0,",
|
|
||||||
" ),",
|
|
||||||
" buffer: \"AQIDBA==\",",
|
" buffer: \"AQIDBA==\",",
|
||||||
" )),",
|
" )),",
|
||||||
" buffer_list: None,",
|
" buffer_list: None,",
|
||||||
|
@ -155,9 +153,7 @@ mod tests {
|
||||||
" ]), None),",
|
" ]), None),",
|
||||||
" ])),",
|
" ])),",
|
||||||
" segment: Some((",
|
" segment: Some((",
|
||||||
" flags: (",
|
" flags: \"reset+segment\",",
|
||||||
" bits: 9,",
|
|
||||||
" ),",
|
|
||||||
" rate: 1,",
|
" rate: 1,",
|
||||||
" applied_rate: 0.9,",
|
" applied_rate: 0.9,",
|
||||||
" format: Time,",
|
" format: Time,",
|
||||||
|
@ -202,17 +198,13 @@ mod tests {
|
||||||
" duration: Some(4),",
|
" duration: Some(4),",
|
||||||
" offset: 0,",
|
" offset: 0,",
|
||||||
" offset_end: 4,",
|
" offset_end: 4,",
|
||||||
" flags: (",
|
" flags: \"\",",
|
||||||
" bits: 0,",
|
|
||||||
" ),",
|
|
||||||
" buffer: \"AQIDBA==\",",
|
" buffer: \"AQIDBA==\",",
|
||||||
" )),",
|
" )),",
|
||||||
" buffer_list: None,",
|
" buffer_list: None,",
|
||||||
" caps: None,",
|
" caps: None,",
|
||||||
" segment: Some((",
|
" segment: Some((",
|
||||||
" flags: (",
|
" flags: \"\",",
|
||||||
" bits: 0,",
|
|
||||||
" ),",
|
|
||||||
" rate: 1,",
|
" rate: 1,",
|
||||||
" applied_rate: 1,",
|
" applied_rate: 1,",
|
||||||
" format: Time,",
|
" format: Time,",
|
||||||
|
@ -244,9 +236,7 @@ mod tests {
|
||||||
duration: Some(4),
|
duration: Some(4),
|
||||||
offset: 0,
|
offset: 0,
|
||||||
offset_end: 4,
|
offset_end: 4,
|
||||||
flags: (
|
flags: "",
|
||||||
bits: 0,
|
|
||||||
),
|
|
||||||
buffer: "AQIDBA==",
|
buffer: "AQIDBA==",
|
||||||
)),
|
)),
|
||||||
buffer_list: None,
|
buffer_list: None,
|
||||||
|
@ -257,9 +247,7 @@ mod tests {
|
||||||
]), None),
|
]), None),
|
||||||
])),
|
])),
|
||||||
segment: Some((
|
segment: Some((
|
||||||
flags: (
|
flags: "",
|
||||||
bits: 0,
|
|
||||||
),
|
|
||||||
rate: 1,
|
rate: 1,
|
||||||
applied_rate: 0.9,
|
applied_rate: 0.9,
|
||||||
format: Time,
|
format: Time,
|
||||||
|
@ -298,9 +286,7 @@ mod tests {
|
||||||
duration: Some(4),
|
duration: Some(4),
|
||||||
offset: 0,
|
offset: 0,
|
||||||
offset_end: 4,
|
offset_end: 4,
|
||||||
flags: (
|
flags: "",
|
||||||
bits: 0,
|
|
||||||
),
|
|
||||||
buffer: "AQIDBA==",
|
buffer: "AQIDBA==",
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
|
|
@ -138,9 +138,7 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok(concat!(
|
Ok(concat!(
|
||||||
"(",
|
"(",
|
||||||
" flags: (",
|
" flags: \"reset+segment\",",
|
||||||
" bits: 9,",
|
|
||||||
" ),",
|
|
||||||
" rate: 1,",
|
" rate: 1,",
|
||||||
" applied_rate: 0.9,",
|
" applied_rate: 0.9,",
|
||||||
" format: Time,",
|
" format: Time,",
|
||||||
|
@ -164,9 +162,7 @@ mod tests {
|
||||||
|
|
||||||
let segment_ron = r#"
|
let segment_ron = r#"
|
||||||
(
|
(
|
||||||
flags: (
|
flags: "reset+segment",
|
||||||
bits: 9,
|
|
||||||
),
|
|
||||||
rate: 1,
|
rate: 1,
|
||||||
applied_rate: 0.9,
|
applied_rate: 0.9,
|
||||||
format: Time,
|
format: Time,
|
||||||
|
@ -228,9 +224,7 @@ mod tests {
|
||||||
|
|
||||||
let segment_ron = r#"
|
let segment_ron = r#"
|
||||||
(
|
(
|
||||||
flags: (
|
flags: "reset+segment",
|
||||||
bits: 9,
|
|
||||||
),
|
|
||||||
rate: 1,
|
rate: 1,
|
||||||
applied_rate: 0.9,
|
applied_rate: 0.9,
|
||||||
format: Time,
|
format: Time,
|
||||||
|
|
145
gstreamer/src/serde_macros.rs
Normal file
145
gstreamer/src/serde_macros.rs
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bitflags_serialize_impl {
|
||||||
|
// this implementation serializes only flags using only one bit,
|
||||||
|
// ignoring all other flags
|
||||||
|
($type:ty, single_bit_flags$(, $feature:expr)?) => {
|
||||||
|
$(#[cfg(any(feature = $feature, feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = $feature)))])?
|
||||||
|
impl serde::Serialize for $type {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let class = FlagsClass::new(Self::static_type()).unwrap();
|
||||||
|
let this = self.to_value();
|
||||||
|
|
||||||
|
let mut handled = Self::empty().to_value();
|
||||||
|
let mut res = String::new();
|
||||||
|
|
||||||
|
for v in class.values() {
|
||||||
|
let value = v.value();
|
||||||
|
if value.count_ones() == 1 && class.is_set(&this, value) && !class.is_set(&handled, value) {
|
||||||
|
if !res.is_empty() {
|
||||||
|
res.push('+');
|
||||||
|
}
|
||||||
|
res.push_str(v.nick());
|
||||||
|
handled = class.set(handled, value).expect("Failed to set flag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer.serialize_str(&res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// considers the flags using the most bits first
|
||||||
|
($type:ty, by_ones_decreasing$(, $feature:expr)?) => {
|
||||||
|
$(#[cfg(any(feature = $feature, feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = $feature)))])?
|
||||||
|
impl serde::Serialize for $type {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
let mut handled = Self::empty();
|
||||||
|
let mut res = String::new();
|
||||||
|
|
||||||
|
static SORTED_VALUES: Lazy<Vec<(u32, String)>> = Lazy::new(|| {
|
||||||
|
let class = FlagsClass::new(<$type>::static_type()).unwrap();
|
||||||
|
let mut sorted_values: Vec<(u32, String)> =
|
||||||
|
class.values().iter()
|
||||||
|
.map(|f| (f.value(), f.nick().to_owned()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
sorted_values.sort_by(|(a, _), (b, _)| {
|
||||||
|
b.count_ones().cmp(&a.count_ones())
|
||||||
|
});
|
||||||
|
|
||||||
|
sorted_values
|
||||||
|
});
|
||||||
|
|
||||||
|
for (bits, nick) in SORTED_VALUES.iter() {
|
||||||
|
// not all values defined in the class are always also defined
|
||||||
|
// in the bitflags struct, see RTPBufferFlags for example
|
||||||
|
if let Some(value) = Self::from_bits(*bits) {
|
||||||
|
if !value.is_empty() && self.contains(value) && !handled.intersects(value) {
|
||||||
|
if !res.is_empty() {
|
||||||
|
res.push('+');
|
||||||
|
}
|
||||||
|
res.push_str(nick);
|
||||||
|
handled.insert(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer.serialize_str(&res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bitflags_deserialize_impl {
|
||||||
|
($type:ty$(, $feature:expr)?) => {
|
||||||
|
$(#[cfg(any(feature = $feature, feature = "dox"))]
|
||||||
|
#[cfg_attr(feature = "dox", doc(cfg(feature = $feature)))])?
|
||||||
|
impl<'de> serde::Deserialize<'de> for $type {
|
||||||
|
fn deserialize<D: serde::de::Deserializer<'de>>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> std::result::Result<Self, D::Error> {
|
||||||
|
skip_assert_initialized!();
|
||||||
|
|
||||||
|
struct FlagsVisitor;
|
||||||
|
|
||||||
|
impl<'de> serde::de::Visitor<'de> for FlagsVisitor {
|
||||||
|
type Value = $type;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str(
|
||||||
|
"one or more mask names separated by plus signs, or the empty string",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E: serde::de::Error>(
|
||||||
|
self,
|
||||||
|
value: &str,
|
||||||
|
) -> std::result::Result<Self::Value, E> {
|
||||||
|
if value.is_empty() {
|
||||||
|
return Ok(Self::Value::empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut gvalue = glib::Value::from_type(Self::Value::static_type());
|
||||||
|
let tokens = value.split('+');
|
||||||
|
let class = FlagsClass::new(Self::Value::static_type()).unwrap();
|
||||||
|
|
||||||
|
for token in tokens {
|
||||||
|
gvalue = class.set_by_nick(gvalue, token).map_err(|_| {
|
||||||
|
serde::de::Error::custom(&format!("Invalid value: {}", token))
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(unsafe {
|
||||||
|
from_glib(glib::gobject_ffi::g_value_get_flags(
|
||||||
|
gvalue.to_glib_none().0,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_str(FlagsVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bitflags_serde_impl {
|
||||||
|
($type:ty$(, $feature:expr)?) => {
|
||||||
|
$crate::bitflags_serialize_impl!($type, single_bit_flags$(, $feature)?);
|
||||||
|
$crate::bitflags_deserialize_impl!($type$(, $feature)?);
|
||||||
|
};
|
||||||
|
}
|
|
@ -387,17 +387,13 @@ mod tests {
|
||||||
r#" duration: None,"#,
|
r#" duration: None,"#,
|
||||||
r#" offset: 0,"#,
|
r#" offset: 0,"#,
|
||||||
r#" offset_end: 0,"#,
|
r#" offset_end: 0,"#,
|
||||||
r#" flags: ("#,
|
r#" flags: "","#,
|
||||||
r#" bits: 0,"#,
|
|
||||||
r#" ),"#,
|
|
||||||
r#" buffer: "AQIDBA==","#,
|
r#" buffer: "AQIDBA==","#,
|
||||||
r#" )),"#,
|
r#" )),"#,
|
||||||
r#" buffer_list: None,"#,
|
r#" buffer_list: None,"#,
|
||||||
r#" caps: None,"#,
|
r#" caps: None,"#,
|
||||||
r#" segment: Some(("#,
|
r#" segment: Some(("#,
|
||||||
r#" flags: ("#,
|
r#" flags: "","#,
|
||||||
r#" bits: 0,"#,
|
|
||||||
r#" ),"#,
|
|
||||||
r#" rate: 1,"#,
|
r#" rate: 1,"#,
|
||||||
r#" applied_rate: 1,"#,
|
r#" applied_rate: 1,"#,
|
||||||
r#" format: Time,"#,
|
r#" format: Time,"#,
|
||||||
|
@ -449,9 +445,7 @@ mod tests {
|
||||||
duration: None,
|
duration: None,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
offset_end: 0,
|
offset_end: 0,
|
||||||
flags: (
|
flags: "",
|
||||||
bits: 0,
|
|
||||||
),
|
|
||||||
buffer: "AQIDBA==",
|
buffer: "AQIDBA==",
|
||||||
)),
|
)),
|
||||||
buffer_list: None,
|
buffer_list: None,
|
||||||
|
@ -500,7 +494,7 @@ mod tests {
|
||||||
["replaygain-track-gain", [1.0]],
|
["replaygain-track-gain", [1.0]],
|
||||||
["date",[{"YMD":[2018,5,28]}]],
|
["date",[{"YMD":[2018,5,28]}]],
|
||||||
["datetime",[{"YMD":[2018,5,28]}]],
|
["datetime",[{"YMD":[2018,5,28]}]],
|
||||||
["image",[{"buffer":{"pts":null,"dts":null,"duration":null,"offset":0,"offset_end":0,"flags":{"bits":0},"buffer":[1,2,3,4]},"buffer_list":null,"caps":null,"segment":null,"info":null}]]
|
["image",[{"buffer":{"pts":null,"dts":null,"duration":null,"offset":0,"offset_end":0,"flags":"","buffer":[1,2,3,4]},"buffer_list":null,"caps":null,"segment":null,"info":null}]]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
Loading…
Reference in a new issue