diff --git a/gstreamer-app/src/app_sink.rs b/gstreamer-app/src/app_sink.rs index 58fa707df..6b15373d8 100644 --- a/gstreamer-app/src/app_sink.rs +++ b/gstreamer-app/src/app_sink.rs @@ -71,6 +71,14 @@ impl AppSinkCallbacksBuilder { } } + pub fn eos_if_some(self, eos: Option) -> Self { + if let Some(eos) = eos { + self.eos(eos) + } else { + self + } + } + pub fn new_preroll< F: FnMut(&AppSink) -> Result + Send + 'static, >( @@ -83,6 +91,19 @@ impl AppSinkCallbacksBuilder { } } + pub fn new_preroll_if_some< + F: FnMut(&AppSink) -> Result + Send + 'static, + >( + self, + new_preroll: Option, + ) -> Self { + if let Some(new_preroll) = new_preroll { + self.new_preroll(new_preroll) + } else { + self + } + } + pub fn new_sample< F: FnMut(&AppSink) -> Result + Send + 'static, >( @@ -95,6 +116,19 @@ impl AppSinkCallbacksBuilder { } } + pub fn new_sample_if_some< + F: FnMut(&AppSink) -> Result + Send + 'static, + >( + self, + new_sample: Option, + ) -> Self { + if let Some(new_sample) = new_sample { + self.new_sample(new_sample) + } else { + self + } + } + #[cfg(feature = "v1_20")] #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))] pub fn new_event bool + Send + 'static>(self, new_event: F) -> Self { @@ -104,6 +138,19 @@ impl AppSinkCallbacksBuilder { } } + #[cfg(feature = "v1_20")] + #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))] + pub fn new_event_if_some bool + Send + 'static>( + self, + new_event: Option, + ) -> Self { + if let Some(new_event) = new_event { + self.new_event(new_event) + } else { + self + } + } + #[cfg(feature = "v1_24")] #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))] pub fn propose_allocation< @@ -118,6 +165,21 @@ impl AppSinkCallbacksBuilder { } } + #[cfg(feature = "v1_24")] + #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))] + pub fn propose_allocation_if_some< + F: FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static, + >( + self, + propose_allocation: Option, + ) -> Self { + if let Some(propose_allocation) = propose_allocation { + self.propose_allocation(propose_allocation) + } else { + self + } + } + #[must_use = "Building the callbacks without using them has no effect"] pub fn build(self) -> AppSinkCallbacks { let have_eos = self.eos.is_some(); diff --git a/gstreamer-app/src/app_src.rs b/gstreamer-app/src/app_src.rs index f8666b654..22ebc8ca6 100644 --- a/gstreamer-app/src/app_src.rs +++ b/gstreamer-app/src/app_src.rs @@ -60,6 +60,17 @@ impl AppSrcCallbacksBuilder { } } + pub fn need_data_if_some( + self, + need_data: Option, + ) -> Self { + if let Some(need_data) = need_data { + self.need_data(need_data) + } else { + self + } + } + pub fn enough_data(self, enough_data: F) -> Self { Self { enough_data: Some(Box::new(enough_data)), @@ -67,6 +78,17 @@ impl AppSrcCallbacksBuilder { } } + pub fn enough_data_if_some( + self, + enough_data: Option, + ) -> Self { + if let Some(enough_data) = enough_data { + self.enough_data(enough_data) + } else { + self + } + } + pub fn seek_data bool + Send + Sync + 'static>( self, seek_data: F, @@ -77,6 +99,17 @@ impl AppSrcCallbacksBuilder { } } + pub fn seek_data_if_some bool + Send + Sync + 'static>( + self, + seek_data: Option, + ) -> Self { + if let Some(seek_data) = seek_data { + self.seek_data(seek_data) + } else { + self + } + } + #[must_use = "Building the callbacks without using them has no effect"] pub fn build(self) -> AppSrcCallbacks { let have_need_data = self.need_data.is_some(); diff --git a/gstreamer-audio/src/audio_info.rs b/gstreamer-audio/src/audio_info.rs index 05b70c4c9..595ba4154 100644 --- a/gstreamer-audio/src/audio_info.rs +++ b/gstreamer-audio/src/audio_info.rs @@ -96,6 +96,17 @@ impl<'a> AudioInfoBuilder<'a> { } } + pub fn positions_if_some( + self, + positions: Option<&'a [crate::AudioChannelPosition]>, + ) -> AudioInfoBuilder<'a> { + if let Some(positions) = positions { + self.positions(positions) + } else { + self + } + } + pub fn flags(self, flags: crate::AudioFlags) -> Self { Self { flags: Some(flags), @@ -103,12 +114,28 @@ impl<'a> AudioInfoBuilder<'a> { } } + pub fn flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.flags(flags) + } else { + self + } + } + pub fn layout(self, layout: crate::AudioLayout) -> Self { Self { layout: Some(layout), ..self } } + + pub fn layout_if_some(self, layout: Option) -> Self { + if let Some(layout) = layout { + self.layout(layout) + } else { + self + } + } } impl AudioInfo { diff --git a/gstreamer-audio/src/caps.rs b/gstreamer-audio/src/caps.rs index e34fe5f64..715209ba5 100644 --- a/gstreamer-audio/src/caps.rs +++ b/gstreamer-audio/src/caps.rs @@ -90,6 +90,14 @@ impl AudioCapsBuilder { } } + pub fn format_if_some(self, format: Option) -> Self { + if let Some(format) = format { + self.format(format) + } else { + self + } + } + pub fn format_list(self, formats: impl IntoIterator) -> Self { Self { builder: self.builder.field( @@ -99,12 +107,31 @@ impl AudioCapsBuilder { } } + pub fn format_list_if_some( + self, + formats: Option>, + ) -> Self { + if let Some(formats) = formats { + self.format_list(formats) + } else { + self + } + } + pub fn rate(self, rate: i32) -> Self { Self { builder: self.builder.field(glib::gstr!("rate"), rate), } } + pub fn rate_if_some(self, rate: Option) -> Self { + if let Some(rate) = rate { + self.rate(rate) + } else { + self + } + } + pub fn rate_range(self, rates: impl RangeBounds) -> Self { let (start, end) = range_bounds_i32_start_end(rates); let gst_rates = gst::IntRange::::new(start, end); @@ -113,6 +140,14 @@ impl AudioCapsBuilder { } } + pub fn rate_range_if_some(self, rates: Option>) -> Self { + if let Some(rates) = rates { + self.rate_range(rates) + } else { + self + } + } + pub fn rate_list(self, rates: impl IntoIterator) -> Self { Self { builder: self @@ -121,12 +156,28 @@ impl AudioCapsBuilder { } } + pub fn rate_list_if_some(self, rates: Option>) -> Self { + if let Some(rates) = rates { + self.rate_list(rates) + } else { + self + } + } + pub fn channels(self, channels: i32) -> Self { Self { builder: self.builder.field(glib::gstr!("channels"), channels), } } + pub fn channels_if_some(self, channels: Option) -> Self { + if let Some(channels) = channels { + self.channels(channels) + } else { + self + } + } + pub fn channels_range(self, channels: impl RangeBounds) -> Self { let (start, end) = range_bounds_i32_start_end(channels); let gst_channels: gst::IntRange = gst::IntRange::new(start, end); @@ -135,6 +186,14 @@ impl AudioCapsBuilder { } } + pub fn channels_range_if_some(self, channels: Option>) -> Self { + if let Some(channels) = channels { + self.channels_range(channels) + } else { + self + } + } + pub fn channels_list(self, channels: impl IntoIterator) -> Self { Self { builder: self @@ -143,6 +202,14 @@ impl AudioCapsBuilder { } } + pub fn channels_list_if_some(self, channels: Option>) -> Self { + if let Some(channels) = channels { + self.channels_list(channels) + } else { + self + } + } + pub fn layout(self, layout: AudioLayout) -> Self { Self { builder: self @@ -151,6 +218,14 @@ impl AudioCapsBuilder { } } + pub fn layout_if_some(self, layout: Option) -> Self { + if let Some(layout) = layout { + self.layout(layout) + } else { + self + } + } + pub fn layout_list(self, layouts: impl IntoIterator) -> Self { Self { builder: self.builder.field( @@ -160,6 +235,17 @@ impl AudioCapsBuilder { } } + pub fn layout_list_if_some( + self, + layouts: Option>, + ) -> Self { + if let Some(layouts) = layouts { + self.layout_list(layouts) + } else { + self + } + } + pub fn channel_mask(self, channel_mask: u64) -> Self { Self { builder: self @@ -168,6 +254,14 @@ impl AudioCapsBuilder { } } + pub fn channel_mask_if_some(self, channel_mask: Option) -> Self { + if let Some(channel_mask) = channel_mask { + self.channel_mask(channel_mask) + } else { + self + } + } + pub fn fallback_channel_mask(self) -> Self { let channels = self.builder.structure().get::(glib::gstr!("channels")); match channels { @@ -187,6 +281,14 @@ impl AudioCapsBuilder { } } + pub fn field_if_some(self, name: &str, value: Option + Send>) -> Self { + if let Some(value) = value { + self.field(name, value) + } else { + self + } + } + #[must_use] pub fn build(self) -> gst::Caps { self.builder.build() diff --git a/gstreamer-pbutils/src/element_properties.rs b/gstreamer-pbutils/src/element_properties.rs index 2d4fa6d3f..f67f6c73e 100644 --- a/gstreamer-pbutils/src/element_properties.rs +++ b/gstreamer-pbutils/src/element_properties.rs @@ -145,11 +145,30 @@ impl ElementPropertiesGeneralBuilder { self } + pub fn field_if_some(self, property_name: &str, value: Option) -> Self + where + T: Into + Send, + { + if let Some(value) = value { + self.field(property_name, value) + } else { + self + } + } + pub fn field_value(mut self, property_name: &str, value: glib::SendValue) -> Self { self.structure.set_value(property_name, value); self } + pub fn field_value_if_some(self, property_name: &str, value: Option) -> Self { + if let Some(value) = value { + self.field_value(property_name, value) + } else { + self + } + } + pub fn build(self) -> ElementProperties { ElementProperties(self.structure) } @@ -167,6 +186,14 @@ impl ElementPropertiesMapBuilder { self } + pub fn item_if_some(self, item: Option) -> Self { + if let Some(item) = item { + self.item(item) + } else { + self + } + } + pub fn build(self) -> ElementProperties { ElementProperties( gst::Structure::builder("element-properties-map") @@ -252,11 +279,30 @@ impl ElementPropertiesMapItemBuilder { self } + pub fn field_if_some(self, property_name: &str, value: Option) -> Self + where + T: Into + Send, + { + if let Some(value) = value { + self.field(property_name, value) + } else { + self + } + } + pub fn field_value(mut self, property_name: &str, value: glib::SendValue) -> Self { self.structure.set_value(property_name, value); self } + pub fn field_value_if_some(self, property_name: &str, value: Option) -> Self { + if let Some(value) = value { + self.field_value(property_name, value) + } else { + self + } + } + pub fn build(self) -> ElementPropertiesMapItem { ElementPropertiesMapItem(self.structure) } diff --git a/gstreamer-pbutils/src/encoding_profile.rs b/gstreamer-pbutils/src/encoding_profile.rs index baf49aa01..406da3994 100644 --- a/gstreamer-pbutils/src/encoding_profile.rs +++ b/gstreamer-pbutils/src/encoding_profile.rs @@ -33,16 +33,40 @@ impl> EncodingProfileExtManual for O {} trait EncodingProfileBuilderCommon { fn set_allow_dynamic_output(&self, allow_dynamic_output: bool); + fn set_allow_dynamic_output_if_some(&self, allow_dynamic_output: Option) { + if let Some(allow_dynamic_output) = allow_dynamic_output { + self.set_allow_dynamic_output(allow_dynamic_output) + } + } + fn set_description(&self, description: Option<&str>); fn set_enabled(&self, enabled: bool); + fn set_enabled_if_some(&self, enabled: Option) { + if let Some(enabled) = enabled { + self.set_enabled(enabled) + } + } + fn set_format(&self, format: &gst::Caps); + fn set_format_if_some(&self, format: Option<&gst::Caps>) { + if let Some(format) = format { + self.set_format(format) + } + } + fn set_name(&self, name: Option<&str>); fn set_presence(&self, presence: u32); + fn set_presence_if_some(&self, presence: Option) { + if let Some(presence) = presence { + self.set_presence(presence); + } + } + fn set_preset(&self, preset: Option<&str>); fn set_preset_name(&self, preset_name: Option<&str>); @@ -52,6 +76,13 @@ trait EncodingProfileBuilderCommon { #[cfg(feature = "v1_20")] fn set_element_properties(&self, element_properties: ElementProperties); + + #[cfg(feature = "v1_20")] + fn set_element_properties_if_some(&self, element_properties: Option) { + if let Some(element_properties) = element_properties { + self.set_element_properties(element_properties); + } + } } impl> EncodingProfileBuilderCommon for O { diff --git a/gstreamer-rtsp-server/src/rtsp_token.rs b/gstreamer-rtsp-server/src/rtsp_token.rs index dfbd65540..efb86fa0a 100644 --- a/gstreamer-rtsp-server/src/rtsp_token.rs +++ b/gstreamer-rtsp-server/src/rtsp_token.rs @@ -107,6 +107,18 @@ impl Builder { self } + pub fn field_if_some( + self, + name: impl IntoGStr, + value: Option + Send>, + ) -> Self { + if let Some(value) = value { + self.field(name, value) + } else { + self + } + } + #[must_use = "Building the structure without using it has no effect"] pub fn build(self) -> RTSPToken { self.token diff --git a/gstreamer-validate/src/action_type.rs b/gstreamer-validate/src/action_type.rs index d7d036245..833a2e3f0 100644 --- a/gstreamer-validate/src/action_type.rs +++ b/gstreamer-validate/src/action_type.rs @@ -77,11 +77,19 @@ impl<'a> ActionParameterBuilder<'a> { /// parameter. For example for the start value of a seek action, we will /// accept to take 'duration' which will be replace by the total duration of /// the stream on which the action is executed. - pub fn add_possible_variable(mut self, possible_variables: &str) -> Self { - self.possible_variables.push(possible_variables.to_owned()); + pub fn add_possible_variable(mut self, possible_variable: &str) -> Self { + self.possible_variables.push(possible_variable.to_owned()); self } + pub fn add_possible_variable_if_some(self, possible_variable: Option<&str>) -> Self { + if let Some(possible_variable) = possible_variable { + self.add_possible_variable(possible_variable) + } else { + self + } + } + pub fn mandatory(mut self) -> Self { self.mandatory = true; self @@ -92,6 +100,14 @@ impl<'a> ActionParameterBuilder<'a> { self } + pub fn default_value_if_some(self, default_value: Option<&'a str>) -> Self { + if let Some(default_value) = default_value { + self.default_value(default_value) + } else { + self + } + } + // rustdoc-stripper-ignore-next /// The types the parameter can take described as a string. /// @@ -103,6 +119,14 @@ impl<'a> ActionParameterBuilder<'a> { self } + pub fn add_type_if_some(self, types: Option<&str>) -> Self { + if let Some(types) = types { + self.add_type(types) + } else { + self + } + } + pub fn build(self) -> ActionParameter { let types = if self.types.is_empty() { ptr::null() @@ -173,21 +197,53 @@ impl<'a> ActionTypeBuilder<'a> { self } + pub fn implementer_namespace_if_some(self, implementer_namespace: Option<&'a str>) -> Self { + if let Some(implementer_namespace) = implementer_namespace { + self.implementer_namespace(implementer_namespace) + } else { + self + } + } + pub fn description(mut self, description: &'a str) -> Self { self.description = Some(description); self } + pub fn description_if_some(self, description: Option<&'a str>) -> Self { + if let Some(description) = description { + self.description(description) + } else { + self + } + } + pub fn parameter(mut self, parameter: ActionParameter) -> Self { self.parameters.push(parameter); self } + pub fn parameter_if_some(self, parameter: Option) -> Self { + if let Some(parameter) = parameter { + self.parameter(parameter) + } else { + self + } + } + pub fn flags(mut self, flags: crate::ActionTypeFlags) -> Self { self.flags |= flags; self } + pub fn flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.flags(flags) + } else { + self + } + } + pub fn build(self) -> crate::ActionType { static QUARK_ACTION_TYPE_FUNC: std::sync::OnceLock = std::sync::OnceLock::new(); diff --git a/gstreamer-video/src/caps.rs b/gstreamer-video/src/caps.rs index 90494ff7d..e5fca200e 100644 --- a/gstreamer-video/src/caps.rs +++ b/gstreamer-video/src/caps.rs @@ -72,6 +72,14 @@ impl VideoCapsBuilder { } } + pub fn format_if_some(self, format: Option) -> Self { + if let Some(format) = format { + self.format(format) + } else { + self + } + } + pub fn format_list(self, formats: impl IntoIterator) -> Self { Self { builder: self.builder.field( @@ -81,12 +89,31 @@ impl VideoCapsBuilder { } } + pub fn format_list_if_some( + self, + formats: Option>, + ) -> Self { + if let Some(formats) = formats { + self.format_list(formats) + } else { + self + } + } + pub fn width(self, width: i32) -> Self { Self { builder: self.builder.field(glib::gstr!("width"), width), } } + pub fn width_if_some(self, width: Option) -> Self { + if let Some(width) = width { + self.width(width) + } else { + self + } + } + pub fn width_range(self, widths: impl RangeBounds) -> Self { let (start, end) = range_bounds_i32_start_end(widths); let gst_widths: gst::IntRange = gst::IntRange::new(start, end); @@ -95,6 +122,14 @@ impl VideoCapsBuilder { } } + pub fn width_range_if_some(self, widths: Option>) -> Self { + if let Some(widths) = widths { + self.width_range(widths) + } else { + self + } + } + pub fn width_list(self, widths: impl IntoIterator) -> Self { Self { builder: self @@ -103,12 +138,28 @@ impl VideoCapsBuilder { } } + pub fn width_list_if_some(self, widths: Option>) -> Self { + if let Some(widths) = widths { + self.width_list(widths) + } else { + self + } + } + pub fn height(self, height: i32) -> Self { Self { builder: self.builder.field(glib::gstr!("height"), height), } } + pub fn height_if_some(self, height: Option) -> Self { + if let Some(height) = height { + self.height(height) + } else { + self + } + } + pub fn height_range(self, heights: impl RangeBounds) -> Self { let (start, end) = range_bounds_i32_start_end(heights); let gst_heights: gst::IntRange = gst::IntRange::new(start, end); @@ -117,6 +168,14 @@ impl VideoCapsBuilder { } } + pub fn height_range_if_some(self, heights: Option>) -> Self { + if let Some(heights) = heights { + self.height_range(heights) + } else { + self + } + } + pub fn height_list(self, heights: impl IntoIterator) -> Self { Self { builder: self @@ -125,12 +184,28 @@ impl VideoCapsBuilder { } } + pub fn height_list_if_some(self, heights: Option>) -> Self { + if let Some(heights) = heights { + self.height_list(heights) + } else { + self + } + } + pub fn framerate(self, framerate: gst::Fraction) -> Self { Self { builder: self.builder.field(glib::gstr!("framerate"), framerate), } } + pub fn framerate_if_some(self, framerate: Option) -> Self { + if let Some(framerate) = framerate { + self.framerate(framerate) + } else { + self + } + } + pub fn framerate_range(self, framerates: impl RangeBounds) -> Self { let start = match framerates.start_bound() { Unbounded => gst::Fraction::new(0, 1), @@ -155,6 +230,17 @@ impl VideoCapsBuilder { } } + pub fn framerate_range_if_some( + self, + framerates: Option>, + ) -> Self { + if let Some(framerates) = framerates { + self.framerate_range(framerates) + } else { + self + } + } + pub fn framerate_list(self, framerates: impl IntoIterator) -> Self { Self { builder: self @@ -163,12 +249,31 @@ impl VideoCapsBuilder { } } + pub fn framerate_list_if_some( + self, + framerates: Option>, + ) -> Self { + if let Some(framerates) = framerates { + self.framerate_list(framerates) + } else { + self + } + } + pub fn pixel_aspect_ratio(self, pixel_aspect_ratio: gst::Fraction) -> Self { Self { builder: self.builder.field("pixel-aspect-ratio", pixel_aspect_ratio), } } + pub fn pixel_aspect_ratio_if_some(self, pixel_aspect_ratio: Option) -> Self { + if let Some(pixel_aspect_ratio) = pixel_aspect_ratio { + self.pixel_aspect_ratio(pixel_aspect_ratio) + } else { + self + } + } + pub fn pixel_aspect_ratio_range( self, pixel_aspect_ratios: impl RangeBounds, @@ -198,6 +303,17 @@ impl VideoCapsBuilder { } } + pub fn pixel_aspect_ratio_range_if_some( + self, + pixel_aspect_ratios: Option>, + ) -> Self { + if let Some(pixel_aspect_ratios) = pixel_aspect_ratios { + self.pixel_aspect_ratio_range(pixel_aspect_ratios) + } else { + self + } + } + pub fn pixel_aspect_ratio_list( self, pixel_aspect_ratios: impl IntoIterator, @@ -209,12 +325,31 @@ impl VideoCapsBuilder { } } + pub fn pixel_aspect_ratio_list_if_some( + self, + pixel_aspect_ratios: Option>, + ) -> Self { + if let Some(pixel_aspect_ratios) = pixel_aspect_ratios { + self.pixel_aspect_ratio_list(pixel_aspect_ratios) + } else { + self + } + } + pub fn field(self, name: &str, value: impl Into + Send) -> Self { Self { builder: self.builder.field(name, value), } } + pub fn field_if_some(self, name: &str, value: Option + Send>) -> Self { + if let Some(value) = value { + self.field(name, value) + } else { + self + } + } + #[must_use] pub fn build(self) -> gst::Caps { self.builder.build() diff --git a/gstreamer-video/src/video_event.rs b/gstreamer-video/src/video_event.rs index 86401756f..87516336d 100644 --- a/gstreamer-video/src/video_event.rs +++ b/gstreamer-video/src/video_event.rs @@ -19,6 +19,14 @@ macro_rules! event_builder_generic_impl { } } + pub fn seqnum_if_some(self, seqnum: Option) -> Self { + if let Some(seqnum) = seqnum { + self.seqnum(seqnum) + } else { + self + } + } + pub fn running_time_offset(self, running_time_offset: i64) -> Self { Self { running_time_offset: Some(running_time_offset), @@ -26,6 +34,14 @@ macro_rules! event_builder_generic_impl { } } + pub fn running_time_offset_if_some(self, running_time_offset: Option) -> Self { + if let Some(running_time_offset) = running_time_offset { + self.running_time_offset(running_time_offset) + } else { + self + } + } + pub fn other_field(self, name: &'a str, value: impl ToSendValue) -> Self { let mut other_fields = self.other_fields; other_fields.push((name, value.to_send_value())); @@ -36,6 +52,14 @@ macro_rules! event_builder_generic_impl { } } + pub fn other_field_if_some(self, name: &'a str, value: Option) -> Self { + if let Some(value) = value { + self.other_field(name, value) + } else { + self + } + } + #[deprecated = "use build.other_field() instead"] pub fn other_fields( self, @@ -135,10 +159,26 @@ impl<'a> DownstreamForceKeyUnitEventBuilder<'a> { } } + pub fn all_headers_if_some(self, all_headers: Option) -> Self { + if let Some(all_headers) = all_headers { + self.all_headers(all_headers) + } else { + self + } + } + pub fn count(self, count: u32) -> Self { Self { count, ..self } } + pub fn count_if_some(self, count: Option) -> Self { + if let Some(count) = count { + self.count(count) + } else { + self + } + } + event_builder_generic_impl!(|s: &mut Self| { ffi::gst_video_event_new_downstream_force_key_unit( s.timestamp.into_glib(), @@ -235,10 +275,26 @@ impl<'a> UpstreamForceKeyUnitEventBuilder<'a> { } } + pub fn all_headers_if_some(self, all_headers: Option) -> Self { + if let Some(all_headers) = all_headers { + self.all_headers(all_headers) + } else { + self + } + } + pub fn count(self, count: u32) -> Self { Self { count, ..self } } + pub fn count_if_some(self, count: Option) -> Self { + if let Some(count) = count { + self.count(count) + } else { + self + } + } + event_builder_generic_impl!(|s: &mut Self| { ffi::gst_video_event_new_upstream_force_key_unit( s.running_time.into_glib(), diff --git a/gstreamer-video/src/video_info.rs b/gstreamer-video/src/video_info.rs index 6a659434b..b08aabecd 100644 --- a/gstreamer-video/src/video_info.rs +++ b/gstreamer-video/src/video_info.rs @@ -446,6 +446,17 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn interlace_mode_if_some( + self, + interlace_mode: Option, + ) -> VideoInfoBuilder<'a> { + if let Some(interlace_mode) = interlace_mode { + self.interlace_mode(interlace_mode) + } else { + self + } + } + pub fn flags(self, flags: crate::VideoFlags) -> Self { Self { flags: Some(flags), @@ -453,6 +464,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.flags(flags) + } else { + self + } + } + pub fn size(self, size: usize) -> Self { Self { size: Some(size), @@ -460,6 +479,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn size_if_some(self, size: Option) -> Self { + if let Some(size) = size { + self.size(size) + } else { + self + } + } + pub fn views(self, views: u32) -> Self { Self { views: Some(views), @@ -467,6 +494,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn views_if_some(self, views: Option) -> Self { + if let Some(views) = views { + self.views(views) + } else { + self + } + } + pub fn chroma_site(self, chroma_site: crate::VideoChromaSite) -> Self { Self { chroma_site: Some(chroma_site), @@ -474,6 +509,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn chroma_site_if_some(self, chroma_site: Option) -> Self { + if let Some(chroma_site) = chroma_site { + self.chroma_site(chroma_site) + } else { + self + } + } + pub fn colorimetry(self, colorimetry: &'a crate::VideoColorimetry) -> VideoInfoBuilder<'a> { Self { colorimetry: Some(colorimetry), @@ -481,6 +524,17 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn colorimetry_if_some( + self, + colorimetry: Option<&'a crate::VideoColorimetry>, + ) -> VideoInfoBuilder<'a> { + if let Some(colorimetry) = colorimetry { + self.colorimetry(colorimetry) + } else { + self + } + } + pub fn par>(self, par: T) -> Self { Self { par: Some(par.into()), @@ -488,6 +542,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn par_if_some>(self, par: Option) -> Self { + if let Some(par) = par { + self.par(par) + } else { + self + } + } + pub fn fps>(self, fps: T) -> Self { Self { fps: Some(fps.into()), @@ -495,6 +557,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn fps_if_some>(self, fps: Option) -> Self { + if let Some(fps) = fps { + self.fps(fps) + } else { + self + } + } + pub fn offset(self, offset: &'a [usize]) -> VideoInfoBuilder<'a> { Self { offset: Some(offset), @@ -502,6 +572,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn offset_if_some(self, offset: Option<&'a [usize]>) -> VideoInfoBuilder<'a> { + if let Some(offset) = offset { + self.offset(offset) + } else { + self + } + } + pub fn stride(self, stride: &'a [i32]) -> VideoInfoBuilder<'a> { Self { stride: Some(stride), @@ -509,6 +587,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn stride_if_some(self, stride: Option<&'a [i32]>) -> VideoInfoBuilder<'a> { + if let Some(stride) = stride { + self.stride(stride) + } else { + self + } + } + pub fn multiview_mode(self, multiview_mode: crate::VideoMultiviewMode) -> Self { Self { multiview_mode: Some(multiview_mode), @@ -516,6 +602,14 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn multiview_mode_if_some(self, multiview_mode: Option) -> Self { + if let Some(multiview_mode) = multiview_mode { + self.multiview_mode(multiview_mode) + } else { + self + } + } + pub fn multiview_flags(self, multiview_flags: crate::VideoMultiviewFlags) -> Self { Self { multiview_flags: Some(multiview_flags), @@ -523,12 +617,31 @@ impl<'a> VideoInfoBuilder<'a> { } } + pub fn multiview_flags_if_some( + self, + multiview_flags: Option, + ) -> Self { + if let Some(multiview_flags) = multiview_flags { + self.multiview_flags(multiview_flags) + } else { + self + } + } + pub fn field_order(self, field_order: crate::VideoFieldOrder) -> Self { Self { field_order: Some(field_order), ..self } } + + pub fn field_order_if_some(self, field_order: Option) -> Self { + if let Some(field_order) = field_order { + self.field_order(field_order) + } else { + self + } + } } impl VideoInfo { diff --git a/gstreamer-video/src/video_message.rs b/gstreamer-video/src/video_message.rs index c19669b55..abc8dd851 100644 --- a/gstreamer-video/src/video_message.rs +++ b/gstreamer-video/src/video_message.rs @@ -20,6 +20,15 @@ macro_rules! message_builder_generic_impl { } } + #[allow(clippy::needless_update)] + pub fn src_if_some + Cast + Clone>(self, src: Option<&O>) -> Self { + if let Some(src) = src { + self.src(src) + } else { + self + } + } + #[doc(alias = "gst_message_set_seqnum")] #[allow(clippy::needless_update)] pub fn seqnum(self, seqnum: Seqnum) -> Self { @@ -29,6 +38,16 @@ macro_rules! message_builder_generic_impl { } } + #[doc(alias = "gst_message_set_seqnum")] + #[allow(clippy::needless_update)] + pub fn seqnum_if_some(self, seqnum: Option) -> Self { + if let Some(seqnum) = seqnum { + self.seqnum(seqnum) + } else { + self + } + } + pub fn other_field(self, name: &'a str, value: impl ToSendValue) -> Self { Self { builder: self.builder.other_field(name, value), @@ -36,6 +55,14 @@ macro_rules! message_builder_generic_impl { } } + pub fn other_field_if_some(self, name: &'a str, value: Option) -> Self { + if let Some(value) = value { + self.other_field(name, value) + } else { + self + } + } + #[deprecated = "use builder.other_field() instead"] #[allow(clippy::needless_update)] pub fn other_fields( diff --git a/gstreamer/src/bin.rs b/gstreamer/src/bin.rs index 885e4ecb3..ad3e1dd37 100644 --- a/gstreamer/src/bin.rs +++ b/gstreamer/src/bin.rs @@ -250,17 +250,41 @@ impl BinBuilder { } } + pub fn async_handling_if_some(self, async_handling: Option) -> Self { + if let Some(async_handling) = async_handling { + self.async_handling(async_handling) + } else { + self + } + } + pub fn message_forward(self, message_forward: bool) -> Self { Self { builder: self.builder.property("message-forward", message_forward), } } + pub fn message_forward_if_some(self, message_forward: Option) -> Self { + if let Some(message_forward) = message_forward { + self.message_forward(message_forward) + } else { + self + } + } + pub fn name(self, name: impl Into) -> Self { Self { builder: self.builder.property("name", name.into()), } } + + pub fn name_if_some(self, name: Option>) -> Self { + if let Some(name) = name { + self.name(name) + } else { + self + } + } } unsafe extern "C" fn do_latency_trampoline< diff --git a/gstreamer/src/caps.rs b/gstreamer/src/caps.rs index b301c1b3a..0e9fcaf32 100644 --- a/gstreamer/src/caps.rs +++ b/gstreamer/src/caps.rs @@ -1013,6 +1013,18 @@ impl Builder { self } + pub fn field_if_some( + self, + name: impl IntoGStr, + value: Option + Send>, + ) -> Self { + if let Some(value) = value { + self.field(name, value) + } else { + self + } + } + #[must_use = "Building the caps without using them has no effect"] pub fn build(self) -> Caps { let mut caps = Caps::new_empty(); @@ -1070,9 +1082,29 @@ impl BuilderFull { self.append_structure(structure, Some(features)) } + pub fn structure_with_features_if_some( + self, + structure: Option, + features: CapsFeatures, + ) -> Self { + if let Some(structure) = structure { + self.structure_with_features(structure, features) + } else { + self + } + } + pub fn structure_with_any_features(self, structure: Structure) -> Self { self.append_structure(structure, Some(CapsFeatures::new_any())) } + + pub fn structure_with_any_features_if_some(self, structure: Option) -> Self { + if let Some(structure) = structure { + self.structure_with_any_features(structure) + } else { + self + } + } } impl BuilderFull { @@ -1114,6 +1146,14 @@ impl BuilderFull { self.append_structure(structure, None) } + pub fn structure_if_some(self, structure: Option) -> Self { + if let Some(structure) = structure { + self.structure(structure) + } else { + self + } + } + #[must_use = "Building the caps without using them has no effect"] pub fn build(self) -> Caps { self.caps @@ -1166,6 +1206,17 @@ mod tests { .features(["foo:bla", "foo:baz"]) .build(); assert_eq!(caps.to_string(), "foo/bar(foo:bla, foo:baz), int=(int)12"); + + let caps = Caps::builder("foo/bar") + .field_if_some("int0", Option::::None) + .field_if_some("int1", Some(12)) + .field_if_some("string0", Option::::None) + .field_if_some("string1", Some("bla")) + .build(); + assert_eq!( + caps.to_string(), + "foo/bar, int1=(int)12, string1=(string)bla" + ); } #[test] @@ -1210,6 +1261,37 @@ mod tests { caps.to_string(), "audio/x-raw(ANY); video/x-raw(foo:bla, foo:baz)" ); + + let caps = Caps::builder_full() + .structure_if_some(Option::::None) + .build(); + assert!(caps.is_empty()); + + let caps = Caps::builder_full() + .structure_if_some(Some(Structure::builder("audio/x-raw").build())) + .build(); + assert_eq!(caps.to_string(), "audio/x-raw"); + + let caps = Caps::builder_full() + .structure_with_any_features_if_some(Some(Structure::builder("audio/x-raw").build())) + .structure_with_features_if_some( + Some(Structure::builder("video/x-raw").build()), + CapsFeatures::new(["foo:bla", "foo:baz"]), + ) + .build(); + assert_eq!( + caps.to_string(), + "audio/x-raw(ANY); video/x-raw(foo:bla, foo:baz)" + ); + + let caps = Caps::builder_full() + .structure_with_any_features_if_some(Option::::None) + .structure_with_features_if_some( + Option::::None, + CapsFeatures::new(["foo:bla", "foo:baz"]), + ) + .build(); + assert!(caps.is_empty()); } #[test] diff --git a/gstreamer/src/element_factory.rs b/gstreamer/src/element_factory.rs index c0f0e803b..7565c0d90 100644 --- a/gstreamer/src/element_factory.rs +++ b/gstreamer/src/element_factory.rs @@ -213,7 +213,18 @@ impl<'a> ElementBuilder<'a> { } // rustdoc-stripper-ignore-next - /// Set property `name` to the given value `value`. + /// Sets the name property to the given `name` if it is `Some`. + #[inline] + pub fn name_if_some(self, name: Option>) -> Self { + if let Some(name) = name { + self.name(name) + } else { + self + } + } + + // rustdoc-stripper-ignore-next + /// Sets property `name` to the given value `value`. #[inline] pub fn property(self, name: &'a str, value: impl Into + 'a) -> Self { Self { @@ -226,6 +237,21 @@ impl<'a> ElementBuilder<'a> { } } + // rustdoc-stripper-ignore-next + /// Sets property `name` to the given value `value` if it is `Some`. + #[inline] + pub fn property_if_some( + self, + name: &'a str, + value: Option + 'a>, + ) -> Self { + if let Some(value) = value { + self.property(name, value) + } else { + self + } + } + // rustdoc-stripper-ignore-next /// Set property `name` to the given string value `value`. #[inline] @@ -240,6 +266,17 @@ impl<'a> ElementBuilder<'a> { } } + // rustdoc-stripper-ignore-next + /// Set property `name` to the given string value `value` if it is `Some`. + #[inline] + pub fn property_from_str_if_some(self, name: &'a str, value: Option<&'a str>) -> Self { + if let Some(value) = value { + self.property_from_str(name, value) + } else { + self + } + } + // rustdoc-stripper-ignore-next /// Build the element with the provided properties. /// diff --git a/gstreamer/src/event.rs b/gstreamer/src/event.rs index 4b527d456..d818c340b 100644 --- a/gstreamer/src/event.rs +++ b/gstreamer/src/event.rs @@ -2098,6 +2098,16 @@ macro_rules! event_builder_generic_impl { } } + #[doc(alias = "gst_event_set_seqnum")] + #[allow(clippy::needless_update)] + pub fn seqnum_if_some(self, seqnum: Option) -> Self { + if let Some(seqnum) = seqnum { + self.seqnum(seqnum) + } else { + self + } + } + #[doc(alias = "gst_event_set_running_time_offset")] #[allow(clippy::needless_update)] pub fn running_time_offset(self, running_time_offset: i64) -> Self { @@ -2107,6 +2117,16 @@ macro_rules! event_builder_generic_impl { } } + #[doc(alias = "gst_event_set_running_time_offset")] + #[allow(clippy::needless_update)] + pub fn running_time_offset_if_some(self, running_time_offset: Option) -> Self { + if let Some(running_time_offset) = running_time_offset { + self.running_time_offset(running_time_offset) + } else { + self + } + } + #[allow(clippy::needless_update)] pub fn other_field(self, name: &'a str, value: impl ToSendValue) -> Self { Self { @@ -2115,6 +2135,15 @@ macro_rules! event_builder_generic_impl { } } + #[allow(clippy::needless_update)] + pub fn other_field_if_some(self, name: &'a str, value: Option) -> Self { + if let Some(value) = value { + self.other_field(name, value) + } else { + self + } + } + #[deprecated = "use build.other_field() instead"] #[allow(clippy::needless_update)] pub fn other_fields( @@ -2219,6 +2248,14 @@ impl<'a> StreamStartBuilder<'a> { } } + pub fn flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.flags(flags) + } else { + self + } + } + pub fn group_id(self, group_id: GroupId) -> Self { Self { group_id: Some(group_id), @@ -2226,6 +2263,14 @@ impl<'a> StreamStartBuilder<'a> { } } + pub fn group_id_if_some(self, group_id: Option) -> Self { + if let Some(group_id) = group_id { + self.group_id(group_id) + } else { + self + } + } + pub fn stream(self, stream: crate::Stream) -> Self { Self { stream: Some(stream), @@ -2233,6 +2278,14 @@ impl<'a> StreamStartBuilder<'a> { } } + pub fn stream_if_some(self, stream: Option) -> Self { + if let Some(stream) = stream { + self.stream(stream) + } else { + self + } + } + event_builder_generic_impl!(|s: &Self| { let ev = ffi::gst_event_new_stream_start(s.stream_id.to_glib_none().0); if let Some(flags) = s.flags { @@ -2501,6 +2554,14 @@ impl<'a> ProtectionBuilder<'a> { } } + pub fn origin_if_some(self, origin: Option<&'a str>) -> Self { + if let Some(origin) = origin { + self.origin(origin) + } else { + self + } + } + event_builder_generic_impl!(|s: &Self| { ffi::gst_event_new_protection( s.system_id.to_glib_none().0, @@ -2558,6 +2619,16 @@ impl<'a> GapBuilder<'a> { self } + #[cfg(feature = "v1_20")] + #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))] + pub fn gap_flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.gap_flags(flags) + } else { + self + } + } + pub fn duration(mut self, duration: impl Into>) -> Self { self.duration = duration.into(); self diff --git a/gstreamer/src/ghost_pad.rs b/gstreamer/src/ghost_pad.rs index ac667d0a5..0295ed987 100644 --- a/gstreamer/src/ghost_pad.rs +++ b/gstreamer/src/ghost_pad.rs @@ -244,6 +244,21 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_activate_function")] + pub fn proxy_pad_activate_function_if_some(self, func: Option) -> Self + where + F: Fn(&crate::ProxyPad, Option<&crate::Object>) -> Result<(), LoggableError> + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_activate_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_activatemode_function")] pub fn proxy_pad_activatemode_function(self, func: F) -> Self where @@ -269,6 +284,26 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_activatemode_function")] + pub fn proxy_pad_activatemode_function_if_some(self, func: Option) -> Self + where + F: Fn( + &crate::ProxyPad, + Option<&crate::Object>, + crate::PadMode, + bool, + ) -> Result<(), LoggableError> + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_activatemode_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_chain_function")] pub fn proxy_pad_chain_function(self, func: F) -> Self where @@ -293,6 +328,25 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_chain_function")] + pub fn proxy_pad_chain_function_if_some(self, func: Option) -> Self + where + F: Fn( + &crate::ProxyPad, + Option<&crate::Object>, + crate::Buffer, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_chain_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_chain_list_function")] pub fn proxy_pad_chain_list_function(self, func: F) -> Self where @@ -317,6 +371,25 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_chain_list_function")] + pub fn proxy_pad_chain_list_function_if_some(self, func: Option) -> Self + where + F: Fn( + &crate::ProxyPad, + Option<&crate::Object>, + crate::BufferList, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_chain_list_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_event_function")] pub fn proxy_pad_event_function(self, func: F) -> Self where @@ -337,6 +410,21 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_event_function")] + pub fn proxy_pad_event_function_if_some(self, func: Option) -> Self + where + F: Fn(&crate::ProxyPad, Option<&crate::Object>, crate::Event) -> bool + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_event_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_event_full_function")] pub fn proxy_pad_event_full_function(self, func: F) -> Self where @@ -361,6 +449,25 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_event_full_function")] + pub fn proxy_pad_event_full_function_if_some(self, func: Option) -> Self + where + F: Fn( + &crate::ProxyPad, + Option<&crate::Object>, + crate::Event, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_event_full_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_getrange_function")] pub fn proxy_pad_getrange_function(self, func: F) -> Self where @@ -387,6 +494,27 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_getrange_function")] + pub fn proxy_pad_getrange_function_if_some(self, func: Option) -> Self + where + F: Fn( + &crate::ProxyPad, + Option<&crate::Object>, + u64, + Option<&mut crate::BufferRef>, + u32, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_getrange_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_iterate_internal_links_function")] pub fn proxy_pad_iterate_internal_links_function(self, func: F) -> Self where @@ -407,6 +535,21 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_iterate_internal_links_function")] + pub fn proxy_pad_iterate_internal_links_function_if_some(self, func: Option) -> Self + where + F: Fn(&crate::ProxyPad, Option<&crate::Object>) -> crate::Iterator + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_iterate_internal_links_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_link_function")] pub fn proxy_pad_link_function(self, func: F) -> Self where @@ -431,6 +574,25 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_link_function")] + pub fn proxy_pad_link_function_if_some(self, func: Option) -> Self + where + F: Fn( + &crate::ProxyPad, + Option<&crate::Object>, + &Pad, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_link_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_query_function")] pub fn proxy_pad_query_function(self, func: F) -> Self where @@ -451,6 +613,21 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_query_function")] + pub fn proxy_pad_query_function_if_some(self, func: Option) -> Self + where + F: Fn(&crate::ProxyPad, Option<&crate::Object>, &mut crate::QueryRef) -> bool + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.proxy_pad_query_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_unlink_function")] pub fn proxy_pad_unlink_function(self, func: F) -> Self where @@ -468,6 +645,18 @@ impl + IsA> PadBuilder { self } + #[doc(alias = "gst_pad_set_unlink_function")] + pub fn proxy_pad_unlink_function_if_some(self, func: Option) -> Self + where + F: Fn(&crate::ProxyPad, Option<&crate::Object>) + Send + Sync + 'static, + { + if let Some(func) = func { + self.proxy_pad_unlink_function(func) + } else { + self + } + } + pub fn proxy_pad_flags(self, flags: PadFlags) -> Self { unsafe { let proxy = self @@ -481,6 +670,14 @@ impl + IsA> PadBuilder { self } + pub fn proxy_pad_flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.proxy_pad_flags(flags) + } else { + self + } + } + // rustdoc-stripper-ignore-next /// Specifies a `target` [`Pad`](crate::Pad) for the [`GhostPad`]. /// diff --git a/gstreamer/src/message.rs b/gstreamer/src/message.rs index d97224d4a..dec584945 100644 --- a/gstreamer/src/message.rs +++ b/gstreamer/src/message.rs @@ -2525,6 +2525,14 @@ macro_rules! message_builder_generic_impl { ..self } } + #[allow(clippy::needless_update)] + pub fn src_if_some + Cast + Clone>(self, src: Option<&O>) -> Self { + if let Some(src) = src { + self.src(src) + } else { + self + } + } #[doc(alias = "gst_message_set_seqnum")] #[allow(clippy::needless_update)] @@ -2535,6 +2543,16 @@ macro_rules! message_builder_generic_impl { } } + #[doc(alias = "gst_message_set_seqnum")] + #[allow(clippy::needless_update)] + pub fn seqnum_if_some(self, seqnum: Option) -> Self { + if let Some(seqnum) = seqnum { + self.seqnum(seqnum) + } else { + self + } + } + #[allow(clippy::needless_update)] pub fn other_field(self, name: &'a str, value: impl ToSendValue) -> Self { Self { @@ -2543,6 +2561,15 @@ macro_rules! message_builder_generic_impl { } } + #[allow(clippy::needless_update)] + pub fn other_field_if_some(self, name: &'a str, value: Option) -> Self { + if let Some(value) = value { + self.other_field(name, value) + } else { + self + } + } + #[deprecated = "use build.other_field() instead"] #[allow(clippy::needless_update)] pub fn other_fields( @@ -2633,6 +2660,14 @@ impl<'a> ErrorBuilder<'a> { } } + pub fn debug_if_some(self, debug: Option<&'a str>) -> Self { + if let Some(debug) = debug { + self.debug(debug) + } else { + self + } + } + pub fn details(self, details: Structure) -> Self { Self { details: Some(details), @@ -2640,6 +2675,14 @@ impl<'a> ErrorBuilder<'a> { } } + pub fn details_if_some(self, details: Option) -> Self { + if let Some(details) = details { + self.details(details) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let details = match s.details.take() { None => ptr::null_mut(), @@ -2682,6 +2725,14 @@ impl<'a> WarningBuilder<'a> { } } + pub fn debug_if_some(self, debug: Option<&'a str>) -> Self { + if let Some(debug) = debug { + self.debug(debug) + } else { + self + } + } + pub fn details(self, details: Structure) -> Self { Self { details: Some(details), @@ -2689,6 +2740,14 @@ impl<'a> WarningBuilder<'a> { } } + pub fn details_if_some(self, details: Option) -> Self { + if let Some(details) = details { + self.details(details) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let details = match s.details.take() { None => ptr::null_mut(), @@ -2731,6 +2790,14 @@ impl<'a> InfoBuilder<'a> { } } + pub fn debug_if_some(self, debug: Option<&'a str>) -> Self { + if let Some(debug) = debug { + self.debug(debug) + } else { + self + } + } + pub fn details(self, details: Structure) -> Self { Self { details: Some(details), @@ -2738,6 +2805,14 @@ impl<'a> InfoBuilder<'a> { } } + pub fn details_if_some(self, details: Option) -> Self { + if let Some(details) = details { + self.details(details) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let details = match s.details.take() { None => ptr::null_mut(), @@ -3029,6 +3104,14 @@ impl<'a> StreamStatusBuilder<'a> { } } + pub fn status_object_if_some(self, status_object: Option) -> Self { + if let Some(status_object) = status_object { + self.status_object(status_object) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let msg = ffi::gst_message_new_stream_status(src, s.type_.into_glib(), s.owner.to_glib_none().0); @@ -3444,6 +3527,14 @@ impl<'a> StreamStartBuilder<'a> { } } + pub fn group_id_if_some(self, group_id: Option) -> Self { + if let Some(group_id) = group_id { + self.group_id(group_id) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let msg = ffi::gst_message_new_stream_start(src); if let Some(group_id) = s.group_id { @@ -3561,6 +3652,14 @@ impl<'a> PropertyNotifyBuilder<'a> { } } + pub fn value_if_some(self, value: Option) -> Self { + if let Some(value) = value { + self.value(value) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let v = s.value.take(); ffi::gst_message_new_property_notify( @@ -3623,6 +3722,17 @@ impl<'a> StreamsSelectedBuilder<'a> { } } + pub fn streams_if_some( + self, + streams: Option>>, + ) -> Self { + if let Some(streams) = streams { + self.streams(streams) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let msg = ffi::gst_message_new_streams_selected(src, s.collection.to_glib_none().0); if let Some(ref streams) = s.streams { @@ -3663,6 +3773,14 @@ impl<'a> RedirectBuilder<'a> { } } + pub fn tag_list_if_some(self, tag_list: Option<&'a TagList>) -> Self { + if let Some(tag_list) = tag_list { + self.tag_list(tag_list) + } else { + self + } + } + pub fn entry_struct(self, entry_struct: Structure) -> Self { Self { entry_struct: Some(entry_struct), @@ -3670,6 +3788,14 @@ impl<'a> RedirectBuilder<'a> { } } + pub fn entry_struct_if_some(self, entry_struct: Option) -> Self { + if let Some(entry_struct) = entry_struct { + self.entry_struct(entry_struct) + } else { + self + } + } + pub fn entries( self, entries: &'a [(&'a str, Option<&'a TagList>, Option<&'a Structure>)], @@ -3681,6 +3807,18 @@ impl<'a> RedirectBuilder<'a> { } } + #[allow(clippy::type_complexity)] + pub fn entries_if_some( + self, + entries: Option<&'a [(&'a str, Option<&'a TagList>, Option<&'a Structure>)]>, + ) -> Self { + if let Some(entries) = entries { + self.entries(entries) + } else { + self + } + } + message_builder_generic_impl!(|s: &mut Self, src| { let entry_struct = s.entry_struct.take(); let entry_struct_ptr = if let Some(entry_struct) = entry_struct { diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs index 36ebb4234..e8402294f 100644 --- a/gstreamer/src/pad.rs +++ b/gstreamer/src/pad.rs @@ -1690,6 +1690,19 @@ impl + IsA + glib::object::IsClass> PadBuilder { } } + // rustdoc-stripper-ignore-next + /// Optionally sets the name of the Pad. + /// + /// This method is convenient when the `name` is provided as an `Option`. + /// If the `name` is `None`, this has no effect. + pub fn name_if_some(self, name: Option) -> Self { + if let Some(name) = name { + self.name(name) + } else { + self + } + } + #[doc(alias = "gst_pad_set_activate_function")] pub fn activate_function(self, func: F) -> Self where @@ -1702,6 +1715,18 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_activate_function")] + pub fn activate_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>) -> Result<(), LoggableError> + Send + Sync + 'static, + { + if let Some(func) = func { + self.activate_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_activatemode_function")] pub fn activatemode_function(self, func: F) -> Self where @@ -1717,6 +1742,21 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_activatemode_function")] + pub fn activatemode_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>, crate::PadMode, bool) -> Result<(), LoggableError> + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.activatemode_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_chain_function")] pub fn chain_function(self, func: F) -> Self where @@ -1732,6 +1772,21 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_chain_function")] + pub fn chain_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>, crate::Buffer) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.chain_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_chain_list_function")] pub fn chain_list_function(self, func: F) -> Self where @@ -1747,6 +1802,21 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_chain_list_function")] + pub fn chain_list_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>, crate::BufferList) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.chain_list_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_event_function")] pub fn event_function(self, func: F) -> Self where @@ -1759,6 +1829,18 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_event_function")] + pub fn event_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>, crate::Event) -> bool + Send + Sync + 'static, + { + if let Some(func) = func { + self.event_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_event_full_function")] pub fn event_full_function(self, func: F) -> Self where @@ -1774,6 +1856,21 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_event_full_function")] + pub fn event_full_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>, crate::Event) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.event_full_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_getrange_function")] pub fn getrange_function(self, func: F) -> Self where @@ -1795,6 +1892,27 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_getrange_function")] + pub fn getrange_function_if_some(self, func: Option) -> Self + where + F: Fn( + &T, + Option<&crate::Object>, + u64, + Option<&mut crate::BufferRef>, + u32, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.getrange_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_iterate_internal_links_function")] pub fn iterate_internal_links_function(self, func: F) -> Self where @@ -1807,6 +1925,18 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_iterate_internal_links_function")] + pub fn iterate_internal_links_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>) -> crate::Iterator + Send + Sync + 'static, + { + if let Some(func) = func { + self.iterate_internal_links_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_link_function")] pub fn link_function(self, func: F) -> Self where @@ -1826,6 +1956,25 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_link_function")] + pub fn link_function_if_some(self, func: Option) -> Self + where + F: Fn( + &T, + Option<&crate::Object>, + &Pad, + ) -> Result + + Send + + Sync + + 'static, + { + if let Some(func) = func { + self.link_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_query_function")] pub fn query_function(self, func: F) -> Self where @@ -1838,6 +1987,18 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_query_function")] + pub fn query_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>, &mut crate::QueryRef) -> bool + Send + Sync + 'static, + { + if let Some(func) = func { + self.query_function(func) + } else { + self + } + } + #[doc(alias = "gst_pad_set_unlink_function")] pub fn unlink_function(self, func: F) -> Self where @@ -1850,12 +2011,32 @@ impl + IsA + glib::object::IsClass> PadBuilder { self } + #[doc(alias = "gst_pad_set_unlink_function")] + pub fn unlink_function_if_some(self, func: Option) -> Self + where + F: Fn(&T, Option<&crate::Object>) + Send + Sync + 'static, + { + if let Some(func) = func { + self.unlink_function(func) + } else { + self + } + } + pub fn flags(self, flags: PadFlags) -> Self { self.pad.set_pad_flags(flags); self } + pub fn flags_if_some(self, flags: Option) -> Self { + if let Some(flags) = flags { + self.flags(flags) + } else { + self + } + } + // rustdoc-stripper-ignore-next /// Builds the [`Pad`]. /// diff --git a/gstreamer/src/pad_template.rs b/gstreamer/src/pad_template.rs index e22b625db..9bd65548d 100644 --- a/gstreamer/src/pad_template.rs +++ b/gstreamer/src/pad_template.rs @@ -119,6 +119,14 @@ impl<'a> PadTemplateBuilder<'a> { } } + pub fn gtype_if_some(self, gtype: Option) -> Self { + if let Some(gtype) = gtype { + self.gtype(gtype) + } else { + self + } + } + #[cfg(feature = "v1_18")] #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))] pub fn documentation_caps(self, documentation_caps: &'a Caps) -> Self { @@ -128,6 +136,16 @@ impl<'a> PadTemplateBuilder<'a> { } } + #[cfg(feature = "v1_18")] + #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))] + pub fn documentation_caps_if_some(self, documentation_caps: Option<&'a Caps>) -> Self { + if let Some(documentation_caps) = documentation_caps { + self.documentation_caps(documentation_caps) + } else { + self + } + } + pub fn build(self) -> Result { let templ = if let Some(gtype) = self.gtype { PadTemplate::with_gtype( diff --git a/gstreamer/src/pipeline.rs b/gstreamer/src/pipeline.rs index c93b6b3f1..4e1dea0e3 100644 --- a/gstreamer/src/pipeline.rs +++ b/gstreamer/src/pipeline.rs @@ -109,15 +109,43 @@ impl PipelineBuilder { } } + pub fn auto_flush_bus_if_some(self, auto_flush_bus: Option) -> Self { + if let Some(auto_flush_bus) = auto_flush_bus { + self.auto_flush_bus(auto_flush_bus) + } else { + self + } + } + pub fn delay(self, delay: u64) -> Self { Self { builder: self.builder.property("delay", delay), } } - pub fn latency(self, latency: crate::ClockTime) -> Self { - Self { - builder: self.builder.property("latency", latency), + pub fn delay_if_some(self, delay: Option) -> Self { + if let Some(delay) = delay { + self.delay(delay) + } else { + self + } + } + + pub fn latency(self, latency: impl Into>) -> Self { + if let Some(latency) = latency.into() { + Self { + builder: self.builder.property("latency", latency), + } + } else { + self + } + } + + pub fn latency_if_some(self, latency: Option) -> Self { + if let Some(latency) = latency { + self.latency(latency) + } else { + self } } @@ -127,15 +155,39 @@ impl PipelineBuilder { } } + pub fn async_handling_if_some(self, async_handling: Option) -> Self { + if let Some(async_handling) = async_handling { + self.async_handling(async_handling) + } else { + self + } + } + pub fn message_forward(self, message_forward: bool) -> Self { Self { builder: self.builder.property("message-forward", message_forward), } } + pub fn message_forward_if_some(self, message_forward: Option) -> Self { + if let Some(message_forward) = message_forward { + self.message_forward(message_forward) + } else { + self + } + } + pub fn name(self, name: impl Into) -> Self { Self { builder: self.builder.property("name", name.into()), } } + + pub fn name_if_some(self, name: Option>) -> Self { + if let Some(name) = name { + self.name(name) + } else { + self + } + } } diff --git a/gstreamer/src/sample.rs b/gstreamer/src/sample.rs index cee3038dd..522601665 100644 --- a/gstreamer/src/sample.rs +++ b/gstreamer/src/sample.rs @@ -32,6 +32,14 @@ impl<'a> SampleBuilder<'a> { } } + pub fn buffer_if_some(self, buffer: Option<&'a Buffer>) -> Self { + if let Some(buffer) = buffer { + self.buffer(buffer) + } else { + self + } + } + pub fn buffer_list(self, buffer_list: &'a BufferList) -> Self { Self { buffer: None, @@ -40,6 +48,14 @@ impl<'a> SampleBuilder<'a> { } } + pub fn buffer_list_if_some(self, buffer_list: Option<&'a BufferList>) -> Self { + if let Some(buffer_list) = buffer_list { + self.buffer_list(buffer_list) + } else { + self + } + } + pub fn caps(self, caps: &'a Caps) -> Self { Self { caps: Some(caps), @@ -47,6 +63,14 @@ impl<'a> SampleBuilder<'a> { } } + pub fn caps_if_some(self, caps: Option<&'a Caps>) -> Self { + if let Some(caps) = caps { + self.caps(caps) + } else { + self + } + } + pub fn segment(self, segment: &'a FormattedSegment) -> Self { Self { segment: Some(segment.upcast_ref()), @@ -54,6 +78,17 @@ impl<'a> SampleBuilder<'a> { } } + pub fn segment_if_some( + self, + segment: Option<&'a FormattedSegment>, + ) -> Self { + if let Some(segment) = segment { + self.segment(segment) + } else { + self + } + } + pub fn info(self, info: Structure) -> Self { Self { info: Some(info), @@ -61,6 +96,14 @@ impl<'a> SampleBuilder<'a> { } } + pub fn info_if_some(self, info: Option) -> Self { + if let Some(info) = info { + self.info(info) + } else { + self + } + } + #[must_use = "Building the sample without using it has no effect"] pub fn build(self) -> Sample { unsafe { diff --git a/gstreamer/src/stream_collection.rs b/gstreamer/src/stream_collection.rs index 0cbae6fbe..d2ba5e495 100644 --- a/gstreamer/src/stream_collection.rs +++ b/gstreamer/src/stream_collection.rs @@ -115,6 +115,15 @@ impl StreamCollectionBuilder { self } + #[doc(alias = "gst_stream_collection_add_stream")] + pub fn stream_if_some(self, stream: Option) -> Self { + if let Some(stream) = stream { + self.stream(stream) + } else { + self + } + } + pub fn streams(self, streams: impl IntoIterator) -> Self { for stream in streams.into_iter() { unsafe { @@ -128,6 +137,14 @@ impl StreamCollectionBuilder { self } + pub fn streams_if_some(self, streams: Option>) -> Self { + if let Some(streams) = streams { + self.streams(streams) + } else { + self + } + } + #[must_use = "Building the stream collection without using it has no effect"] pub fn build(self) -> StreamCollection { self.0 diff --git a/gstreamer/src/structure.rs b/gstreamer/src/structure.rs index 557eb9b1b..416fa950c 100644 --- a/gstreamer/src/structure.rs +++ b/gstreamer/src/structure.rs @@ -499,6 +499,17 @@ impl StructureRef { self.set_value(name, value); } + #[doc(alias = "gst_structure_set")] + pub fn set_if_some( + &mut self, + name: impl IntoGStr, + value: Option + Send>, + ) { + if let Some(value) = value { + self.set(name, value); + } + } + #[doc(alias = "gst_structure_set_value")] pub fn set_value(&mut self, name: impl IntoGStr, value: SendValue) { unsafe { @@ -508,12 +519,30 @@ impl StructureRef { } } + #[doc(alias = "gst_structure_set_value")] + pub fn set_value_if_some(&mut self, name: impl IntoGStr, value: Option) { + if let Some(value) = value { + self.set_value(name, value); + } + } + #[doc(alias = "gst_structure_id_set")] pub fn set_by_quark(&mut self, name: glib::Quark, value: impl Into + Send) { let value = glib::SendValue::from_owned(value); self.set_value_by_quark(name, value); } + #[doc(alias = "gst_structure_id_set")] + pub fn set_by_quark_if_some( + &mut self, + name: glib::Quark, + value: Option + Send>, + ) { + if let Some(value) = value { + self.set_by_quark(name, value); + } + } + #[doc(alias = "gst_structure_id_set_value")] pub fn set_value_by_quark(&mut self, name: glib::Quark, value: SendValue) { unsafe { @@ -521,6 +550,13 @@ impl StructureRef { } } + #[doc(alias = "gst_structure_id_set_value")] + pub fn set_value_by_quark_if_some(&mut self, name: glib::Quark, value: Option) { + if let Some(value) = value { + self.set_value_by_quark(name, value); + } + } + #[doc(alias = "get_name")] #[doc(alias = "gst_structure_get_name")] pub fn name<'a>(&self) -> &'a glib::GStr { @@ -539,6 +575,13 @@ impl StructureRef { } } + #[doc(alias = "gst_structure_set_name")] + pub fn set_name_if_some(&mut self, name: Option) { + if let Some(name) = name { + self.set_name(name); + } + } + #[doc(alias = "gst_structure_has_name")] pub fn has_name(&self, name: &str) -> bool { self.name() == name @@ -1121,6 +1164,18 @@ impl Builder { self } + pub fn field_if_some( + self, + name: impl IntoGStr, + value: Option + Send>, + ) -> Self { + if let Some(value) = value { + self.field(name, value) + } else { + self + } + } + #[must_use = "Building the structure without using it has no effect"] pub fn build(self) -> Structure { self.s @@ -1143,6 +1198,7 @@ mod tests { s.set("f1", "abc"); s.set("f2", &String::from("bcd")); s.set("f3", 123i32); + s.set("f5", Some("efg")); assert_eq!(s.get::<&str>("f1"), Ok("abc")); assert_eq!(s.get::>("f2"), Ok(Some("bcd"))); @@ -1151,6 +1207,7 @@ mod tests { assert_eq!(s.get_optional::<&str>("f4"), Ok(None)); assert_eq!(s.get_optional::("f3"), Ok(Some(123i32))); assert_eq!(s.get_optional::("f4"), Ok(None)); + assert_eq!(s.get::<&str>("f5"), Ok("efg")); assert_eq!( s.get::("f2"), @@ -1172,23 +1229,38 @@ mod tests { ); assert_eq!(s.get::("f4"), Err(GetError::new_field_not_found("f4"))); - assert_eq!(s.fields().collect::>(), vec!["f1", "f2", "f3"]); + assert_eq!(s.fields().collect::>(), vec!["f1", "f2", "f3", "f5"]); let v = s.iter().map(|(f, v)| (f, v.clone())).collect::>(); - assert_eq!(v.len(), 3); + assert_eq!(v.len(), 4); assert_eq!(v[0].0, "f1"); assert_eq!(v[0].1.get::<&str>(), Ok("abc")); assert_eq!(v[1].0, "f2"); assert_eq!(v[1].1.get::<&str>(), Ok("bcd")); assert_eq!(v[2].0, "f3"); assert_eq!(v[2].1.get::(), Ok(123i32)); + assert_eq!(v[3].0, "f5"); + assert_eq!(v[3].1.get::<&str>(), Ok("efg")); let s2 = Structure::builder("test") .field("f1", "abc") .field("f2", String::from("bcd")) .field("f3", 123i32) + .field_if_some("f4", Option::::None) + .field_if_some("f5", Some("efg")) + .field_if_some("f6", Option::<&str>::None) .build(); assert_eq!(s, s2); + + let mut s3 = Structure::new_empty("test"); + + s3.set_if_some("f1", Some("abc")); + s3.set_if_some("f2", Some(String::from("bcd"))); + s3.set_if_some("f3", Some(123i32)); + s3.set_if_some("f4", Option::::None); + s3.set_if_some("f5", Some("efg")); + s3.set_if_some("f6", Option::<&str>::None); + assert_eq!(s, s3); } #[test] diff --git a/gstreamer/src/task.rs b/gstreamer/src/task.rs index ce56a1c9f..da1da6ead 100644 --- a/gstreamer/src/task.rs +++ b/gstreamer/src/task.rs @@ -22,6 +22,17 @@ impl TaskBuilder { ..self } } + #[doc(alias = "gst_task_set_enter_callback")] + pub fn enter_callback_if_some( + self, + enter_callback: Option, + ) -> Self { + if let Some(enter_callback) = enter_callback { + self.enter_callback(enter_callback) + } else { + self + } + } #[doc(alias = "gst_task_set_leave_callback")] pub fn leave_callback(self, leave_callback: E) -> Self { @@ -31,6 +42,18 @@ impl TaskBuilder { } } + #[doc(alias = "gst_task_set_leave_callback")] + pub fn leave_callback_if_some( + self, + leave_callback: Option, + ) -> Self { + if let Some(leave_callback) = leave_callback { + self.leave_callback(leave_callback) + } else { + self + } + } + #[doc(alias = "gst_task_set_lock")] pub fn lock(self, lock: &TaskLock) -> Self { Self { @@ -39,6 +62,15 @@ impl TaskBuilder { } } + #[doc(alias = "gst_task_set_lock")] + pub fn lock_if_some(self, lock: Option<&TaskLock>) -> Self { + if let Some(lock) = lock { + self.lock(lock) + } else { + self + } + } + #[doc(alias = "gst_task_new")] pub fn build(self) -> Task { unsafe extern "C" fn func_trampoline(