This commit makes the formatted values' main constructors `const`,
so that they can be used in constant definitions.
`from_usize` constructors can't be made const because `try_into`
can't be used in `const` functions as of rustc 1.64.0. Same for
`Percent::from_ratio`: floating point arithmetic is not allowed.
Introduce a set of Constructor traits which are implemented on
integer of float depending on the formatted values. This traits
allows building formatted values using expressions such as:
```rust
let buffer_nb = 20.buffers();
let size = 42.k_bytes();
let duration = 15.minutes() + 30.seconds();
let quantity = 42.default_format();
let progress = 20.percent();
let progress = 0.2.percent_ratio();
```
Previous proposition for constructing specific formatted values was
to use an operation such as `42 * Default::ONE` which, in retrospect,
doesn't seem idiomatic.
This commit adds `from_u64` and `from_usize` constructors for most
formatted values. Having `from_usize` is convenient when dealing with
quantities related to containers indices or length.
This also fixes the `Percent` from float constructors from which was
derived the `ONE` constant as well as previous display implementation.
Also removed the `pub` specifier for `Undefined` inner value. It wasn't
removed in a previous commit as `Undefined` can use the full range of
the inner type. But now, it seems preferable not to expose the inner
value for proper encapsulation and so as to reduce the differences with
other formatted values (kind of least astonishment principle).
... users would be able to bypass the range checks and build a
defined Rust value which would be interpreted as `None` in C code.
Added format module examples for formatted values constructions.
- The `GST_FORMAT_PERCENT_SCALE` was not used to compute the value
to display.
- Added `Display` examples in the format module documentation.
- Simplified `glib_newtype_display` macro.
The `Signed` version for `GenericFormattedValue` was implemented as
`Signed<GenericFormattedValue>`, which failed to represent properly
the `None` variants when applicable and could represent inconsistent
`Signed` variant combined with `GenericFormattedValue` formats which
are internaly represented as signed integers.
Some operations were implemented on types that wouldn't result in
the expected physical unit. E.g.:
- `ClockTime / ClockTime` results in a unit-less factor.
- `u64 / ClockTime` would result in a `1 / ClockTime`. Since we don't
use any `Frequency` type, this operation is removed. Users should
use the `ClockTime` accessors to compute the expected value.
This commit also adds:
- multiplications with integers as the left hand side operands.
- `Partial{Eq,Ord} for `Signed<T>` with `T` as left hand side operand.
- `opt_add` / `opt_sub` for `Signed<T>` with `T` as left or right hand
side operands.
- missing tests for `Partial{Eq,Ord}` and `OptionOrd`.
This implementation can interfere with unrelated code and was removed:
- `Signed<usize>.` `PartialOrd` makes existing code computing the len
of slices needing type annotation because the len is later used in
a comparison for which the compiler is unable to determine if
the len is `Signed<usize>` or `usize`.
The `SpecificFormattedValue` types are newtypes of `u64` or `u32`
and they all implement `Copy`. It shouldn't be needed to implement
operations on `&Type` nor `&inner_type`.
The functions `into_{signed,positive,negative}` used to be implemented
on the `FormattedValue` trait for convenience. This was wrong for the
following reasons:
- They aren't specific to `FormattedValue`s: they can also be
implemented for regular unsigned integers such as `u64`, `usize` or
`u32`.
- They were implemented for `format::Undefined` and all variants of
`GenericFormattedValue`, some of which are already signed.
This commit introduces the new trait `UnsignedIntoSigned`, which makes
it possible to fix both of the above problems.
Users can build a `Signed` from an `Undefined`, an `i64`, `isize` or
`i32` thanks to the `From` trait implementations.
Previous implementation for the glib format new types built a
`String` for the displayable value. This commit uses `fmt`
mechanisms so as to limit useless allocations.
Using `ClockTime::from_nseconds` it was possible to build a valid
`ClockTime` which would match `GST_CLOCK_TIME_NONE` when passed to
the C API, leading to unexpected behaviour as `GST_CLOCK_TIME_NONE`
is represented as an `Option::<ClockTime>::None` in Rust.
This commit panics when this function is called with
`GST_CLOCK_TIME_NONE` (defined as `u64::MAX`). This is similar to
what happens when calling other `ClockTime` constructors (e.g.
`from_seconds`) with too large a value: the internal multiplication
overflows leading to a panic.
When the `format_args!` macro is used, formatted args are evaluated
in order to form the argument collection that ends up being formatted
when requested to do so.
For the log macro, this means that any argument that is an expression
was evaluated even if the log level was below current threshold. This
can be examplified by the following code:
```rust
gst::debug!(CAT, "{}", {
println!("fmt arg executed");
"A debug log"
});
```
This used to print "fmt arg executed" even when the log threshold for
`CAT` was filtering `debug` out.
Note that this could break existing code that would incorrectly rely
on the side effect.
When I introduced the 'ser_de' feature, I couldn't find a way to
name it 'serde' while also make it pull the optional 'serde'
crate together with the other related dependencies.
With rustc >= 1.60 we can use 'dep:serde' to refer to the 'serde'
dependency as part of the 'serde' feature.
warning: unused return value of `std::boxed::Box::<T>::from_raw` that must be used
--> gstreamer-rtsp-server/src/rtsp_session_pool.rs:23:5
|
23 | Box::<F>::from_raw(ptr as *mut _);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: call `drop(from_raw(ptr))` if you intend to drop the `Box`
Functions such as Segment::to_running_time_full replicate the C
signature for the return type: an integer indicates whether the
resulting value must be interpreted as positive or negative.
In Rust, alternatives are usually represented using an enum.
This commit implements an enum wrapper to represent the sign
and adds functions to FormattedValue to ease Signed handling.
The trait CompatibleFormattedValue can be used to check argument
compatibility to a certain Format. This is convenient to define
function which accept several FormattedValues which must hold
values of the same Format.
This trait enforces format compatibility at compilation time for
SpecificFormattedValues and at runtime when a GenericFormattedValue
is provided.
See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1059
The trait FormattedValue was only implemented on types which
could implement the full range of values for a Format. In order
to declare a function which could take both the intrinsic type
of any Format (e.g. `ClockTime`) as well the full range of values
(e.g. `Option<ClockTime>`), the argument was declared:
```rust
impl Into<GenericFormattedValue>,
```
This commit implements `FormattedValue` for any type representing
a format. E.g.: both `ClockTime` and `Option<ClockTime>` will now
implement `FormattedValue`. The trait `FormattedValueFullRange`
is implemented on types which can be built from any raw value.
These changes are intended to help for the implementation of a
means to enforce format conformity at compilation time for
functions with multiple formatted value arguments.
The following signatures were found to be incorrect and are fixed:
- `message::StepDone`: forced the type for `amount` and `duration`
to be of the same type, when `duration` is expected to be of the
`Time` format.
- `query::Convert::set`: the two arguments were forced to the same
type, so potentialy the same format, unless a
`GenericFormattedValue` was used.
See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1059
And only allow setting documentation caps via that. It's not actually
allowed to update the documentation caps at random times as it is not
thread-safe.
Represents combinations of flags with a '+' separated string of nicks,
or an empty string for no flags set.
Note that most flag types will ignore any flags using multiple bits when
serializing, since in most cases these flags cover all used bits.
They don't add any safety as this is via unsafe code anyway and are not
needed to get mutable references in this context anyway, while adding a
bit of runtime overhead.
warning: this expression borrows a value the compiler would automatically borrow
--> gstreamer-rtsp-server/src/rtsp_session_pool.rs:16:5
|
16 | (&mut *func.borrow_mut())(&from_glib_borrow(pool)).into_glib()
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: change this to: `(*func.borrow_mut())`
|
= note: `#[warn(clippy::needless_borrow)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
For pre-1.20 simply use `%s` as format string instead of escaping the
`%` inline while writing. This allows a simpler implementation and is
also faster, see https://github.com/gtk-rs/gtk-rs-core/pull/583.
It's quite quite common to use similar macros in the form `log::debug!`
or `glib::clone!`. This MR renames the gst log macros so that we can
`gst::debug!` instead of `gst_debug!` and whithout the need for
`use gst::gst_debug`.
This reverts commit 8226c94110.
Now that GStreamer 1.20 is out, the v1_20 feature can and should link
directly to the stable release instead of the unstable 1.19 development
release.
When we have a view like `Caps<&EventRef>`, we can return a `CapsRef`
borrowing from the wrapped `EventRef`. This way, the `CapsRef` we return
can outlive the view itself.
This is in contrast to a `Caps<Event>` view which owns the `Event`.
Here, the `CapsRef` we return cannot outlive the view.
gstreamer-rs 0.18 consolidated code and treated everything like the
latter case. Fix this by duplicating the accessors for each case.
Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/367
When serializing a structure, if it contains a nested structure
the serialization / deserialization code goes through value_serde,
which was lacking support for Structure.
This makes it clearer than a plain `bool` or `Result<Option<Buffer>, Option<Buffer>>`.
Also pass a `&Buffer` instead of a `&BufferRef` to the immutable foreach
function to allow taking references of the buffer outside the scope of
the closure by cloning instead of requiring a full copy.
And also replace `%` with `%%` for < 1.20 inline, and for >= 1.20 use
the new `gst_debug_log_literal()` function that doesn't require this and
also reduces string allocations further.
The modules format and clock_time share common macros which are
scattered between each modules. This cross reference makes it
difficult to maintain the macros.
This commit also make it possible to use macro
impl_common_ops_for_newtype_uint for Percent.
These operations were implemented using the integer implementations.
These types' MAX values are different from the integers so they must
use specific implementations.
Also add the overflowing variants.
The usual use of this will be through the `ElementImpl::metadata`
method, which requires a `&'static` reference to `ElementMetadata` to be
returned, so we better make it easy to construct these (without forcing
people to resort to `Lazy`'n'stuff)
Attributes don't do anything when applied to macro invocations:
warning: unused attribute `doc`
--> gstreamer/src/lib.rs:146:29
|
146 | #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_attributes)]` on by default
note: the built-in attribute `doc` will be ignored, since it's applied to the macro invocation `cfg_if::cfg_if`
--> gstreamer/src/lib.rs:147:1
|
147 | cfg_if::cfg_if! {
| ^^^^^^^^^^^^^^
And, on line 294-295:
warning: unused attribute `doc`
--> gstreamer/src/lib.rs:294:33
|
294 | #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the built-in attribute `doc` will be ignored, since it's applied to the macro invocation `cfg_if::cfg_if`
--> gstreamer/src/lib.rs:295:5
|
295 | cfg_if::cfg_if! {
| ^^^^^^^^^^^^^^
Fortunately these two `cfg_if`'s for the Unix and Windows bus already
apply unnecessary trickery that duplicates the `mod`s and `use`s in
order to get documenation for both no matter the target platform; we can
capitalize on that by removing the `cfg_if` altogether and instead
applying the `cfg` and `doc(cfg())` attributes directly.
The `links` annotation in `Cargo.toml` is intended to ensure that in the
crate graph there's at most one crate that's an implementation of
some sort concept.
This can make sense in some scenarios, most prominent of which is when
the crate defines `#[no_mangle]` symbols (e.g. by compiling a vendored C
library.) In that situation linking a binary that depends on two
versions of the library cannot work because of colliding symbol names.
There does not appear to be a similar reason to impose such a
restriction on the users of `gstreamer-sys` and similar, however. All of
these crates link to a system library, they do not define any
`#[no_mangle]` symbols nor they vendor and build C libraries as part of
their build process. All they do is linking to a system library. Most
likely all the different versions of the bindings will link to the exact
same library too.
I haven't seen any global resources that these bindings use to ensure
soundness of the library, either.
Gir now uses analyzed objects to generate documentation, and to know
exactly what is available. Additionally, this allows more bindings to
be generated.
This version adds a `--strip-docs` flag to `generator.py`, used in
conjunction with `--strip-docs --embed-docs` to clean documentation
first before re-embedding it (otherwise the same text would show up
multiple times). It is also used in the CI to check that no
documentation disappears on stripping, ie. all documentation is properly
annotated with `// rustdoc-stripper-ignore-next`.
When importing the prelude of a crate like `gst` the `glib` prelude is
provided too. Shedding these imports saves quite a few lines and
adheres to keeping it simple; we're not reexporting base/parent preludes
for no reason :)
This was temporarily allowed by Value trait refactoring, but the root
cause of the unused imports has been found (`glib::ToValue` for property
getters) and fixed in https://github.com/gtk-rs/gir/pull/1117.
In gir it was brought up [1] that some traits (in particular
`*ExtManual`) are exported from the crate root in addition to the
prelude, cluttering the environment unnecessarily. This commit removes
all these reexports, leaving those in prelude (that were already there)
only.
After this commit everything matching `Ext(Manual)?\b` in `lib.rs` sits
within `pub mod prelude {};`.
[1]: https://github.com/gtk-rs/gir/pull/1111
The `lgpl-docs` and documentation embedding step is now solely invoked
from `./gir/generator.py` in the CI, and does not need the embed/purge
build features anymore.
The `lgpl-docs` crate and all precompiled (easy to get outdated!)
docmentation files are removed in favour of being generated at runtime
by the improved generator, both during local development as well as in
the CI.
The previous commit reinstantiated `girs_dir`, and this commit applies
the rename to `girs_directories` and adds the new/missing
`gst-gir-files` directory where GStreamer-specific `.gir` files live.
This reverts commit 7f9fcb09e2.
`generator.py` is in the process of being moved to a generic place in
the `gir` repository for reuse across crates. This means `-d` cannot be
passed for our GStreamer-specific `gst-gir-files` directory anymore, and
should be configured from `Gir.toml` instead.
We can't return a plain reference to something stored inside the future
as that would go out of scope after `await`. Instead return a struct
that wraps the `gst::Promise`, derefs to a structure and keeps the
promise alive as long as needed.
See https://github.com/gtk-rs/gtk-rs/pull/449. This struct remains
vital in GStreamer code to tie a type to an (untyped) SendValue, so that
the underlying value can be retrieved without having to guess its type.
That type is anyway stored in a private member T::TagType.
Co-authored-by: Marijn Suijten <marijns95@gmail.com>
Gir now prints all directories and their hashes in the version file and
comments; useful now that gstreamer-rs is being generated from both
gir-files/ and gst-gir-files/ submodules.
We were already using `gir -d` and especially now that our files are
separated across two directories that are relative to the directory
containing Gir.toml this only becomes cumbersome. Besides `gir` lacks
functionality to normalize the path, leading to ie.
gstreamer-gl/egl/sys/../../../gir-files in the version comment as a
result.
This scales better as there will only be only such data instead of two
or more when having deeper class hierarchies with multiple Rust
elements, and also makes it unnecessary to use a special instance struct
so the default works well.