Draft: Use `imp Into<Option<_>>` in argument position as much as possible
This allows users to call the corresponding functions without the
need to embed the argument in Some(_)
.
I applied this approach to manual code and I moved Bin::new
and Pipeline::new
to manual code to implement it too there.
Many auto
functions could take advantage of this but that would
require a gir
evolution. We could probably apply this to
App{Sink,Src}::set_caps
manually though.
See the result in the examples
and in this (WIP) gst-plugins-rs
branch: https://gitlab.freedesktop.org/fengalin/gst-plugins-rs/-/tree/nullability-into-option-args
When the user wants to pass None
, most of the time, the compiler
is able to infer the type:
let buf = pool.acquire_buffer(None).unwrap();
However, when the function uses a trait
bound for the optional
argument type, user must disambiguate the type. Ex.:
alloc_query.add_allocation_pool::<gst::BufferPool>(None, 1024, 1, 4);
For most types, the NONE
constant is also available:
alloc_query.add_allocation_pool(gst::BufferPool::NONE, 1024, 1, 4);
Merge request reports
Activity
I applied the test on the unmodified API:
- We can use
a.add_allocation_pool(crate::BufferPool::NONE, 1024, 1, 4)
. - We can't use
a.add_allocation_pool(None, ..)
:cannot infer type of the type parameter
T
declared on the enumOption
- We can't use
a.add_allocation_pool::<crate::BufferPool>(None, ..)
but we could if we moved thecrate::BufferPool
as a generic argument instead of using current arg type:pool: Option<&impl IsA<crate::BufferPool>>
. This is what I had to do to have the compiler accept theInto<Option<_>>
stuff.
- We can use
- Resolved by François Laignel
30 30 31 31 impl Bin { 32 32 pub const NONE: Option<&'static Bin> = None; 33 34 #[doc(alias = "gst_bin_new")] 35 pub fn new(name: Option<&str>) -> Bin { Based on my discussion on Matrix, let's get the generator fixed then and get this specific change in right after the release.
Fixing the code generator should be a matter of reverting one of my PRs from a couple of years ago when we went the opposite direction because the compiler was making usage of such code unnecessarily hard. That seems to have been solved in the compiler in the meantime.
12 12 use std::ptr; 13 13 14 14 pub trait DeviceImpl: DeviceImplExt + GstObjectImpl + Send + Sync { 15 fn create_element(&self, name: Option<&str>) -> Result<Element, LoggableError> { 15 fn create_element<'a>( 16 &self, 17 name: impl Into<Option<&'a str>>, 22 25 } 23 26 24 27 pub trait DeviceImplExt: ObjectSubclass { 25 fn parent_create_element(&self, name: Option<&str>) -> Result<Element, LoggableError>; 28 fn parent_create_element<'a>( 29 &self, 30 name: impl Into<Option<&'a str>>, added 1 commit
- d032e721 - Use `imp Into<Option<_>>` in argument position as much as possible
105 105 } 106 106 107 107 #[doc(alias = "gst_bus_create_watch")] 108 pub fn create_watch<F>(&self, name: Option<&str>, priority: Priority, func: F) -> glib::Source 108 pub fn create_watch<'a, F>( 109 &self, 110 name: impl Into<Option<&'a str>>, mentioned in commit fengalin/gst-plugins-rs@10f03c57
Because of constraints in the trait resolution, I guess. Smells like https://github.com/rust-lang/rust/issues/102839 .
&String
was working because it was dereffed automatically to a&str
, but with the trait around here the autoderef does not happen anymoreReference: https://github.com/gtk-rs/gir/pull/1149
Indeed. See
query::Uri::set_uri
as an example in !1134 (merged)
mentioned in commit fengalin/gstreamer-rs@4cb52ab9
mentioned in commit fengalin/gstreamer-rs@58bab5d4
mentioned in commit fengalin/gstreamer-rs@e5eeb839
mentioned in commit fengalin/gstreamer-rs@59154898
mentioned in merge request !1134 (merged)
mentioned in commit fengalin/gstreamer-rs@b50bc260
mentioned in commit fengalin/gstreamer-rs@5ed6eff2