mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-05-19 16:58:22 +00:00
Compare commits
6 commits
707f03cd47
...
a611cf70f2
Author | SHA1 | Date | |
---|---|---|---|
a611cf70f2 | |||
953e3747f2 | |||
a77022ba0e | |||
8dd9a2d5ee | |||
1438fa88db | |||
08169aca96 |
|
@ -23,6 +23,7 @@ num-rational = { version = "0.4", default-features = false, features = [] }
|
||||||
futures-core = "0.3"
|
futures-core = "0.3"
|
||||||
futures-channel = "0.3"
|
futures-channel = "0.3"
|
||||||
futures-util = { version = "0.3", default-features = false }
|
futures-util = { version = "0.3", default-features = false }
|
||||||
|
log = { version = "0.4", optional = true }
|
||||||
muldiv = "1"
|
muldiv = "1"
|
||||||
opt-ops = { package = "option-operations", version = "0.5" }
|
opt-ops = { package = "option-operations", version = "0.5" }
|
||||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||||
|
@ -48,6 +49,7 @@ v1_20 = ["ffi/v1_20", "v1_18"]
|
||||||
v1_22 = ["ffi/v1_22", "v1_20"]
|
v1_22 = ["ffi/v1_22", "v1_20"]
|
||||||
v1_24 = ["ffi/v1_24", "v1_22"]
|
v1_24 = ["ffi/v1_24", "v1_22"]
|
||||||
serde = ["num-rational/serde", "dep:serde", "serde_bytes"]
|
serde = ["num-rational/serde", "dep:serde", "serde_bytes"]
|
||||||
|
log = ["dep:log"]
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|
|
@ -56,6 +56,8 @@ impl GhostPad {
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a new [`GhostPad`] with an automatically generated name.
|
/// Creates a new [`GhostPad`] with an automatically generated name.
|
||||||
///
|
///
|
||||||
|
/// The [`Pad`] will be assigned the usual `gst::Object` generated unique name.
|
||||||
|
///
|
||||||
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
/// and define options.
|
/// and define options.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
||||||
|
@ -65,10 +67,7 @@ impl GhostPad {
|
||||||
}
|
}
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a [`PadBuilder`](crate::PadBuilder) for a [`PadBuilder`] with an automatically generated name.
|
/// Creates a [`PadBuilder`](crate::PadBuilder) with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
|
||||||
/// to specify a different name.
|
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
#[doc(alias = "gst_ghost_pad_new_no_target")]
|
||||||
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -82,12 +81,15 @@ impl GhostPad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `GhostPad` will automatically be named after the `name_template`.
|
/// the `GhostPad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
|
/// and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
|
||||||
/// and define options.
|
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
||||||
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -103,6 +105,9 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
||||||
/// to specify a different name.
|
/// to specify a different name.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
|
||||||
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -116,12 +121,15 @@ impl GhostPad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `GhostPad` will automatically be named after the `name_template`.
|
/// the `GhostPad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
|
/// and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
|
|
||||||
/// and define options.
|
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
||||||
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -137,6 +145,9 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
||||||
/// to specify a different name.
|
/// to specify a different name.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
||||||
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -150,6 +161,9 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`GhostPad::builder_with_target()`] to get a [`PadBuilder`](crate::PadBuilder)
|
/// Use [`GhostPad::builder_with_target()`] to get a [`PadBuilder`](crate::PadBuilder)
|
||||||
/// and define options.
|
/// and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new")]
|
#[doc(alias = "gst_ghost_pad_new")]
|
||||||
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
target: &P,
|
target: &P,
|
||||||
|
@ -165,13 +179,15 @@ impl GhostPad {
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
/// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name)
|
||||||
/// to specify a different name.
|
/// to specify a different name.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
|
||||||
pub fn builder_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn builder_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
target: &P,
|
target: &P,
|
||||||
) -> Result<PadBuilder<Self>, glib::BoolError> {
|
) -> Result<PadBuilder<Self>, glib::BoolError> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
let mut builder = Self::builder(target.direction());
|
let builder = Self::builder(target.direction());
|
||||||
builder.needs_specific_name = true;
|
|
||||||
builder.with_target(target)
|
builder.with_target(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +202,9 @@ impl GhostPad {
|
||||||
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
||||||
/// if it is compatible. Otherwise, a specific name must be provided using
|
/// if it is compatible. Otherwise, a specific name must be provided using
|
||||||
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
||||||
pub fn from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
templ: &crate::PadTemplate,
|
templ: &crate::PadTemplate,
|
||||||
|
@ -206,6 +225,9 @@ impl GhostPad {
|
||||||
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
||||||
/// if it is compatible. Otherwise, a specific name must be provided using
|
/// if it is compatible. Otherwise, a specific name must be provided using
|
||||||
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
#[doc(alias = "gst_ghost_pad_new_from_template")]
|
||||||
pub fn builder_from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn builder_from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
templ: &crate::PadTemplate,
|
templ: &crate::PadTemplate,
|
||||||
|
@ -689,6 +711,9 @@ impl<T: IsA<GhostPad> + IsA<Pad>> PadBuilder<T> {
|
||||||
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
/// If the `name_template` is a wildcard-name, then the `target` `name` is used,
|
||||||
/// if it is compatible. Otherwise, a specific name must be provided using
|
/// if it is compatible. Otherwise, a specific name must be provided using
|
||||||
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
/// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::maybe_name`](crate::PadBuilder::maybe_name).
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
|
||||||
mut self,
|
mut self,
|
||||||
target: &P,
|
target: &P,
|
||||||
|
@ -696,92 +721,8 @@ impl<T: IsA<GhostPad> + IsA<Pad>> PadBuilder<T> {
|
||||||
assert_eq!(self.pad.direction(), target.direction());
|
assert_eq!(self.pad.direction(), target.direction());
|
||||||
|
|
||||||
self.pad.set_target(Some(target))?;
|
self.pad.set_target(Some(target))?;
|
||||||
|
self.name =
|
||||||
if self.needs_specific_name {
|
crate::pad::PadBuilderName::CandidateForWildcardTemplate(target.name().to_string());
|
||||||
let mut can_assign_target_name = true;
|
|
||||||
|
|
||||||
if let Some(pad_template) = self.pad.pad_template() {
|
|
||||||
if pad_template.presence() == crate::PadPresence::Request {
|
|
||||||
// Check if the target name is compatible with the name template.
|
|
||||||
use crate::CAT_RUST;
|
|
||||||
|
|
||||||
let target_name = target.name();
|
|
||||||
let mut target_parts = target_name.split('_');
|
|
||||||
for template_part in pad_template.name_template().split('_') {
|
|
||||||
let Some(target_part) = target_parts.next() else {
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': not enough parts compared to template '{}'",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(conv_spec_start) = template_part.find('%') {
|
|
||||||
if conv_spec_start > 0
|
|
||||||
&& !target_part.starts_with(&template_part[..conv_spec_start])
|
|
||||||
{
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': mismatch template '{}' prefix",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let conv_spec_pos = conv_spec_start + 1;
|
|
||||||
match template_part.get(conv_spec_pos..=conv_spec_pos) {
|
|
||||||
Some("s") => {
|
|
||||||
// *There can be only one* %s
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Some("u") => {
|
|
||||||
if target_part
|
|
||||||
.get(conv_spec_start..)
|
|
||||||
.map_or(true, |s| s.parse::<u32>().is_err())
|
|
||||||
{
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': can't parse '%u' from '{target_part}' (template '{}')",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some("d") => {
|
|
||||||
if target_part
|
|
||||||
.get(conv_spec_start..)
|
|
||||||
.map_or(true, |s| s.parse::<i32>().is_err())
|
|
||||||
{
|
|
||||||
crate::debug!(
|
|
||||||
CAT_RUST,
|
|
||||||
"Not using target Pad name '{target_name}': can't parse '%i' from '{target_part}' (template '{}')",
|
|
||||||
pad_template.name_template(),
|
|
||||||
);
|
|
||||||
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
other => unreachable!("Unexpected conversion specifier {other:?}"),
|
|
||||||
}
|
|
||||||
} else if target_part != template_part {
|
|
||||||
can_assign_target_name = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if can_assign_target_name {
|
|
||||||
self.pad.set_property("name", target.name());
|
|
||||||
self.needs_specific_name = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
@ -911,6 +852,13 @@ mod tests {
|
||||||
.name("ghost_test")
|
.name("ghost_test")
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(ghost_pad.name(), "ghost_test");
|
assert_eq!(ghost_pad.name(), "ghost_test");
|
||||||
|
|
||||||
|
let target = crate::Pad::from_template(&templ);
|
||||||
|
let ghost_pad = GhostPad::builder_with_target(&target)
|
||||||
|
.unwrap()
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(ghost_pad.name().starts_with("ghostpad"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -952,6 +900,13 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(ghost_pad.name(), "my-sink");
|
assert_eq!(ghost_pad.name(), "my-sink");
|
||||||
|
|
||||||
|
let target = crate::Pad::from_template(&sink_templ);
|
||||||
|
let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
|
||||||
|
.unwrap()
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(ghost_pad.name().starts_with("ghostpad"));
|
||||||
|
|
||||||
// # Request template %u
|
// # Request template %u
|
||||||
let wildcard_u_templ = crate::PadTemplate::new(
|
let wildcard_u_templ = crate::PadTemplate::new(
|
||||||
"sink_%u",
|
"sink_%u",
|
||||||
|
@ -983,6 +938,13 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(ghost_pad.name(), "sink_0");
|
assert_eq!(ghost_pad.name(), "sink_0");
|
||||||
|
|
||||||
|
let target = crate::Pad::from_template(&sink_0_templ);
|
||||||
|
let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
|
||||||
|
.unwrap()
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(ghost_pad.name().starts_with("ghostpad"));
|
||||||
|
|
||||||
// # Request template %d_%u
|
// # Request template %d_%u
|
||||||
let wildcard_u_templ = crate::PadTemplate::new(
|
let wildcard_u_templ = crate::PadTemplate::new(
|
||||||
"sink_%d_%u",
|
"sink_%d_%u",
|
||||||
|
|
|
@ -49,6 +49,8 @@ mod serde_macros;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod log;
|
pub mod log;
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
pub use crate::log::DebugCategoryLogger;
|
||||||
pub use crate::log::{
|
pub use crate::log::{
|
||||||
DebugCategory, DebugLogFunction, DebugMessage, LoggedObject, CAT_BUFFER, CAT_BUFFER_LIST,
|
DebugCategory, DebugLogFunction, DebugMessage, LoggedObject, CAT_BUFFER, CAT_BUFFER_LIST,
|
||||||
CAT_BUS, CAT_CALL_TRACE, CAT_CAPS, CAT_CLOCK, CAT_CONTEXT, CAT_DEFAULT, CAT_ELEMENT_PADS,
|
CAT_BUS, CAT_CALL_TRACE, CAT_CAPS, CAT_CLOCK, CAT_CONTEXT, CAT_DEFAULT, CAT_ELEMENT_PADS,
|
||||||
|
|
|
@ -4,6 +4,8 @@ use std::{borrow::Cow, ffi::CStr, fmt, ptr};
|
||||||
|
|
||||||
use glib::{ffi::gpointer, prelude::*, translate::*};
|
use glib::{ffi::gpointer, prelude::*, translate::*};
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
use log;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
use crate::DebugLevel;
|
use crate::DebugLevel;
|
||||||
|
@ -1064,6 +1066,54 @@ macro_rules! log_with_level(
|
||||||
}};
|
}};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DebugCategoryLogger(DebugCategory);
|
||||||
|
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
impl DebugCategoryLogger {
|
||||||
|
pub fn new(cat: DebugCategory) -> Self {
|
||||||
|
Self(cat)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_level(level: log::Level) -> crate::DebugLevel {
|
||||||
|
match level {
|
||||||
|
log::Level::Error => DebugLevel::Error,
|
||||||
|
log::Level::Warn => DebugLevel::Warning,
|
||||||
|
log::Level::Info => DebugLevel::Info,
|
||||||
|
log::Level::Debug => DebugLevel::Debug,
|
||||||
|
log::Level::Trace => DebugLevel::Trace,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
impl log::Log for DebugCategoryLogger {
|
||||||
|
fn enabled(&self, metadata: &log::Metadata) -> bool {
|
||||||
|
let lvl = DebugCategoryLogger::to_level(metadata.level());
|
||||||
|
is_active() && self.0.above_threshold(lvl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, record: &log::Record) {
|
||||||
|
if !self.enabled(record.metadata()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let lvl = DebugCategoryLogger::to_level(record.level());
|
||||||
|
let file = record.file().unwrap_or("");
|
||||||
|
let file = glib::GStr::from_str_until_nul(file).unwrap_or_default();
|
||||||
|
self.0.log(
|
||||||
|
None::<&glib::Object>,
|
||||||
|
lvl,
|
||||||
|
file,
|
||||||
|
record.module_path().unwrap_or(""),
|
||||||
|
record.line().unwrap_or(0),
|
||||||
|
record.args().clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn log_handler<T>(
|
unsafe extern "C" fn log_handler<T>(
|
||||||
category: *mut ffi::GstDebugCategory,
|
category: *mut ffi::GstDebugCategory,
|
||||||
level: ffi::GstDebugLevel,
|
level: ffi::GstDebugLevel,
|
||||||
|
@ -1308,6 +1358,65 @@ mod tests {
|
||||||
memdump!(cat, obj: obj, "meh");
|
memdump!(cat, obj: obj, "meh");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
static LOGGER: Lazy<DebugCategoryLogger> = Lazy::new(|| {
|
||||||
|
DebugCategoryLogger::new(DebugCategory::new(
|
||||||
|
"Log_trait",
|
||||||
|
crate::DebugColorFlags::empty(),
|
||||||
|
Some("Using the Log trait"),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "log")]
|
||||||
|
fn log_trait() {
|
||||||
|
crate::init().unwrap();
|
||||||
|
|
||||||
|
log::set_logger(&(*LOGGER)).expect("Failed to set logger");
|
||||||
|
log::set_max_level(log::LevelFilter::Trace);
|
||||||
|
log::error!("meh");
|
||||||
|
log::warn!("fish");
|
||||||
|
|
||||||
|
let (sender, receiver) = mpsc::channel();
|
||||||
|
let sender = Arc::new(Mutex::new(sender));
|
||||||
|
let handler = move |category: DebugCategory,
|
||||||
|
level: DebugLevel,
|
||||||
|
_file: &glib::GStr,
|
||||||
|
_function: &glib::GStr,
|
||||||
|
_line: u32,
|
||||||
|
_object: Option<&LoggedObject>,
|
||||||
|
message: &DebugMessage| {
|
||||||
|
let cat = DebugCategory::get("Log_trait").unwrap();
|
||||||
|
|
||||||
|
if category != cat {
|
||||||
|
// This test can run in parallel with other tests, including new_and_log above.
|
||||||
|
// We cannot be certain we only see our own messages.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(level, DebugLevel::Error);
|
||||||
|
assert_eq!(message.get().unwrap().as_ref(), "meh");
|
||||||
|
let _ = sender.lock().unwrap().send(());
|
||||||
|
};
|
||||||
|
|
||||||
|
remove_default_log_function();
|
||||||
|
add_log_function(handler);
|
||||||
|
|
||||||
|
let cat = LOGGER.0;
|
||||||
|
|
||||||
|
cat.set_threshold(crate::DebugLevel::Warning);
|
||||||
|
log::error!("meh");
|
||||||
|
receiver.recv().unwrap();
|
||||||
|
|
||||||
|
cat.set_threshold(crate::DebugLevel::Error);
|
||||||
|
log::error!("meh");
|
||||||
|
receiver.recv().unwrap();
|
||||||
|
|
||||||
|
cat.set_threshold(crate::DebugLevel::None);
|
||||||
|
log::error!("fish");
|
||||||
|
log::warn!("meh");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn log_handler() {
|
fn log_handler() {
|
||||||
crate::init().unwrap();
|
crate::init().unwrap();
|
||||||
|
|
|
@ -1428,7 +1428,7 @@ impl Pad {
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a new [`Pad`] with the specified [`PadDirection`](crate::PadDirection).
|
/// Creates a new [`Pad`] with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
///
|
||||||
/// An automatically generated name will be assigned.
|
/// The [`Pad`] will be assigned the usual `gst::Object` generated unique name.
|
||||||
///
|
///
|
||||||
/// Use [`Pad::builder()`] to get a [`PadBuilder`] and define options.
|
/// Use [`Pad::builder()`] to get a [`PadBuilder`] and define options.
|
||||||
#[doc(alias = "gst_pad_new")]
|
#[doc(alias = "gst_pad_new")]
|
||||||
|
@ -1439,8 +1439,6 @@ impl Pad {
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a [`PadBuilder`] with the specified [`PadDirection`](crate::PadDirection).
|
/// Creates a [`PadBuilder`] with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
|
||||||
/// An automatically generated name will be assigned.
|
|
||||||
#[doc(alias = "gst_pad_new")]
|
#[doc(alias = "gst_pad_new")]
|
||||||
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1454,11 +1452,14 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`Pad::builder_from_static_template()`] to get a [`PadBuilder`] and define options.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`Pad::builder_from_static_template()`] to get a [`PadBuilder`] and define options.
|
|
||||||
#[doc(alias = "gst_pad_new_from_static_template")]
|
#[doc(alias = "gst_pad_new_from_static_template")]
|
||||||
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1472,7 +1473,8 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_pad_new_from_static_template")]
|
#[doc(alias = "gst_pad_new_from_static_template")]
|
||||||
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1486,11 +1488,11 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
|
/// Use [`Pad::builder_from_template()`] to get a [`PadBuilder`] and define options.
|
||||||
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if the `name_template` is a wildcard-name.
|
/// Panics if the `name_template` is a wildcard-name.
|
||||||
///
|
|
||||||
/// Use [`Pad::builder_from_template()`] to get a [`PadBuilder`] and define options.
|
|
||||||
#[doc(alias = "gst_pad_new_from_template")]
|
#[doc(alias = "gst_pad_new_from_template")]
|
||||||
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1504,7 +1506,8 @@ impl Pad {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[doc(alias = "gst_pad_new_from_template")]
|
#[doc(alias = "gst_pad_new_from_template")]
|
||||||
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
@ -1558,18 +1561,22 @@ impl Pad {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) enum PadBuilderName {
|
||||||
|
Undefined,
|
||||||
|
KeepGenerated,
|
||||||
|
UserDefined(String),
|
||||||
|
CandidateForWildcardTemplate(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use = "The builder must be built to be used"]
|
#[must_use = "The builder must be built to be used"]
|
||||||
pub struct PadBuilder<T> {
|
pub struct PadBuilder<T> {
|
||||||
pub(crate) pad: T,
|
pub(crate) pad: T,
|
||||||
pub(crate) needs_specific_name: bool,
|
pub(crate) name: PadBuilderName,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Creates a `PadBuilder` with the specified [`PadDirection`](crate::PadDirection).
|
/// Creates a `PadBuilder` with the specified [`PadDirection`](crate::PadDirection).
|
||||||
///
|
|
||||||
/// An automatically generated name will be assigned. Use [`PadBuilder::name`] or
|
|
||||||
/// [`PadBuilder::maybe_name`] to define a specific name.
|
|
||||||
pub fn new(direction: crate::PadDirection) -> Self {
|
pub fn new(direction: crate::PadDirection) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
@ -1588,7 +1595,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
|
|
||||||
PadBuilder {
|
PadBuilder {
|
||||||
pad,
|
pad,
|
||||||
needs_specific_name: false,
|
name: PadBuilderName::Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1599,7 +1606,8 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
|
||||||
skip_assert_initialized!();
|
skip_assert_initialized!();
|
||||||
|
|
||||||
|
@ -1614,7 +1622,8 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
/// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
|
||||||
/// the `Pad` will automatically be named after the `name_template`.
|
/// the `Pad` will automatically be named after the `name_template`.
|
||||||
///
|
///
|
||||||
/// Use [`PadBuilder::name`] or [`PadBuilder::maybe_name`] to specify a different name.
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
pub fn from_template(templ: &crate::PadTemplate) -> Self {
|
||||||
assert_initialized_main_thread!();
|
assert_initialized_main_thread!();
|
||||||
|
|
||||||
|
@ -1654,25 +1663,23 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let needs_specific_name = if templ.name().find('%').is_some() {
|
|
||||||
// Pad needs a specific name
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
pad.set_property("name", templ.name());
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
PadBuilder {
|
PadBuilder {
|
||||||
pad,
|
pad,
|
||||||
needs_specific_name,
|
name: PadBuilderName::Undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rustdoc-stripper-ignore-next
|
||||||
|
/// Uses the `gst::Object` generated unique name.
|
||||||
|
pub fn generated_name(mut self) -> Self {
|
||||||
|
self.name = PadBuilderName::KeepGenerated;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
// rustdoc-stripper-ignore-next
|
// rustdoc-stripper-ignore-next
|
||||||
/// Sets the name of the Pad.
|
/// Sets the name of the Pad.
|
||||||
pub fn name(mut self, name: impl glib::IntoGStr) -> Self {
|
pub fn name(mut self, name: impl Into<String>) -> Self {
|
||||||
name.run_with_gstr(|name| self.pad.set_property("name", name));
|
self.name = PadBuilderName::UserDefined(name.into());
|
||||||
self.needs_specific_name = false;
|
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1682,7 +1689,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
///
|
///
|
||||||
/// This method is convenient when the `name` is provided as an `Option`.
|
/// This method is convenient when the `name` is provided as an `Option`.
|
||||||
/// If the `name` is `None`, this has no effect.
|
/// If the `name` is `None`, this has no effect.
|
||||||
pub fn maybe_name<N: glib::IntoGStr>(self, name: Option<N>) -> Self {
|
pub fn maybe_name<N: Into<String>>(self, name: Option<N>) -> Self {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
self.name(name)
|
self.name(name)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1695,7 +1702,7 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
///
|
///
|
||||||
/// This method is convenient when the `name` is provided as an `Option`.
|
/// This method is convenient when the `name` is provided as an `Option`.
|
||||||
/// If the `name` is `None`, this has no effect.
|
/// If the `name` is `None`, this has no effect.
|
||||||
pub fn name_if_some<N: glib::IntoGStr>(self, name: Option<N>) -> Self {
|
pub fn name_if_some<N: Into<String>>(self, name: Option<N>) -> Self {
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
self.name(name)
|
self.name(name)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2047,18 +2054,132 @@ impl<T: IsA<Pad> + IsA<glib::Object> + glib::object::IsClass> PadBuilder<T> {
|
||||||
/// and no specific `name` was provided using [`PadBuilder::name`]
|
/// and no specific `name` was provided using [`PadBuilder::name`]
|
||||||
/// or [`PadBuilder::maybe_name`], or for [`GhostPad`s](crate::GhostPad),
|
/// or [`PadBuilder::maybe_name`], or for [`GhostPad`s](crate::GhostPad),
|
||||||
/// by defining a `target`.
|
/// by defining a `target`.
|
||||||
|
///
|
||||||
|
/// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
|
||||||
|
/// automatically generated unique name.
|
||||||
#[must_use = "Building the pad without using it has no effect"]
|
#[must_use = "Building the pad without using it has no effect"]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn build(self) -> T {
|
pub fn build(self) -> T {
|
||||||
if self.needs_specific_name {
|
let Self { pad, name } = self;
|
||||||
panic!(concat!(
|
|
||||||
"Attempt to build a Pad from a wildcard-name template",
|
let templ = pad.pad_template();
|
||||||
" or with a target Pad with an incompatible name.",
|
|
||||||
" Make sure to define a specific name using PadBuilder.",
|
use PadBuilderName::*;
|
||||||
));
|
match (name, templ) {
|
||||||
|
(KeepGenerated, _) => (),
|
||||||
|
(Undefined, None) => (),
|
||||||
|
(Undefined, Some(templ)) => {
|
||||||
|
if templ.name().find('%').is_some() {
|
||||||
|
panic!(concat!(
|
||||||
|
"Attempt to build a Pad from a wildcard-name template",
|
||||||
|
" or with a target Pad with an incompatible name.",
|
||||||
|
" Make sure to define a specific name using PadBuilder",
|
||||||
|
" or opt-in to keep the automatically generated name.",
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
pad.set_property("name", templ.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(UserDefined(name), _) | (CandidateForWildcardTemplate(name), None) => {
|
||||||
|
pad.set_property("name", name);
|
||||||
|
}
|
||||||
|
(CandidateForWildcardTemplate(name), Some(templ)) => {
|
||||||
|
if templ.name().find('%').is_none() {
|
||||||
|
// Not a widlcard template
|
||||||
|
pad.set_property("name", templ.name());
|
||||||
|
} else {
|
||||||
|
let mut can_assign_name = true;
|
||||||
|
|
||||||
|
if templ.presence() == crate::PadPresence::Request {
|
||||||
|
// Check if the name is compatible with the name template.
|
||||||
|
use crate::CAT_RUST;
|
||||||
|
|
||||||
|
let mut name_parts = name.split('_');
|
||||||
|
for templ_part in templ.name_template().split('_') {
|
||||||
|
let Some(name_part) = name_parts.next() else {
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using Pad name '{name}': not enough parts compared to template '{}'",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(conv_spec_start) = templ_part.find('%') {
|
||||||
|
if conv_spec_start > 0
|
||||||
|
&& !name_part.starts_with(&templ_part[..conv_spec_start])
|
||||||
|
{
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using Pad name '{name}': mismatch template '{}' prefix",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let conv_spec_pos = conv_spec_start + 1;
|
||||||
|
match templ_part.get(conv_spec_pos..=conv_spec_pos) {
|
||||||
|
Some("s") => {
|
||||||
|
// *There can be only one* %s
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Some("u") => {
|
||||||
|
if name_part
|
||||||
|
.get(conv_spec_start..)
|
||||||
|
.map_or(true, |s| s.parse::<u32>().is_err())
|
||||||
|
{
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using Pad name '{name}': can't parse '%u' from '{name_part}' (template '{}')",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some("d") => {
|
||||||
|
if name_part
|
||||||
|
.get(conv_spec_start..)
|
||||||
|
.map_or(true, |s| s.parse::<i32>().is_err())
|
||||||
|
{
|
||||||
|
crate::debug!(
|
||||||
|
CAT_RUST,
|
||||||
|
"Not using target Pad name '{name}': can't parse '%i' from '{name_part}' (template '{}')",
|
||||||
|
templ.name_template(),
|
||||||
|
);
|
||||||
|
|
||||||
|
can_assign_name = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other => {
|
||||||
|
unreachable!("Unexpected conversion specifier {other:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if name_part != templ_part {
|
||||||
|
can_assign_name = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if can_assign_name {
|
||||||
|
pad.set_property("name", name);
|
||||||
|
} else {
|
||||||
|
panic!(concat!(
|
||||||
|
"Attempt to build a Pad from a wildcard-name template",
|
||||||
|
" with a target Pad with an incompatible name.",
|
||||||
|
" Make sure to define a specific name using PadBuilder",
|
||||||
|
" or opt-in to keep the automatically generated name.",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pad
|
pad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2484,11 +2605,21 @@ mod tests {
|
||||||
let pad = crate::Pad::builder(crate::PadDirection::Unknown).build();
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown).build();
|
||||||
assert!(pad.name().starts_with("pad"));
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
|
.generated_name()
|
||||||
|
.build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
.maybe_name(None::<&str>)
|
.maybe_name(None::<&str>)
|
||||||
.build();
|
.build();
|
||||||
assert!(pad.name().starts_with("pad"));
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
|
.name_if_some(None::<&str>)
|
||||||
|
.build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
let pad = crate::Pad::builder(crate::PadDirection::Sink)
|
let pad = crate::Pad::builder(crate::PadDirection::Sink)
|
||||||
.name("sink_0")
|
.name("sink_0")
|
||||||
.build();
|
.build();
|
||||||
|
@ -2509,6 +2640,11 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert_eq!(pad.name(), "test");
|
assert_eq!(pad.name(), "test");
|
||||||
|
|
||||||
|
let pad = crate::Pad::builder(crate::PadDirection::Unknown)
|
||||||
|
.name_if_some(Some("test"))
|
||||||
|
.build();
|
||||||
|
assert_eq!(pad.name(), "test");
|
||||||
|
|
||||||
let caps = crate::Caps::new_any();
|
let caps = crate::Caps::new_any();
|
||||||
let templ = crate::PadTemplate::new(
|
let templ = crate::PadTemplate::new(
|
||||||
"sink",
|
"sink",
|
||||||
|
@ -2526,6 +2662,9 @@ mod tests {
|
||||||
.build();
|
.build();
|
||||||
assert!(pad.name().starts_with("audio_sink"));
|
assert!(pad.name().starts_with("audio_sink"));
|
||||||
|
|
||||||
|
let pad = Pad::builder_from_template(&templ).generated_name().build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
|
|
||||||
let templ = crate::PadTemplate::new(
|
let templ = crate::PadTemplate::new(
|
||||||
"audio_%u",
|
"audio_%u",
|
||||||
crate::PadDirection::Sink,
|
crate::PadDirection::Sink,
|
||||||
|
@ -2536,6 +2675,9 @@ mod tests {
|
||||||
|
|
||||||
let pad = Pad::builder_from_template(&templ).name("audio_0").build();
|
let pad = Pad::builder_from_template(&templ).name("audio_0").build();
|
||||||
assert!(pad.name().starts_with("audio_0"));
|
assert!(pad.name().starts_with("audio_0"));
|
||||||
|
|
||||||
|
let pad = Pad::builder_from_template(&templ).generated_name().build();
|
||||||
|
assert!(pad.name().starts_with("pad"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue