APIs with multiple
Element::seek takes 2 FormattedValues: one for
and one for
stop. Currently, theses args are defined as being
of the same type using a single bind clause:
fn seek<V: Into<GenericFormattedValue>>( ... start: V, ... stop: V, ) -> ...
When called with a
this signature ensures at compilation time that
use the same format. However, this prevents the user from calling
seek with e.g. an intrinsic value for
start and an
element.seek( ... gst::ClockTime::ZERO, ... gst::ClockTime::NONE, ).unwrap();
Another example that would fail at compilation time would be
start and a
Changes in this MR
This MR implements a solution to make the above APIs flexible
and safe to use. It strives to enforce type conformity at
compilation time when possible and fallbacks to runtime checks
in the case of
In order to ease the transition to a model which would implement
the above, a first pass on the
format module was performed.
The first commit implements the trait
FormattedValue for any
type that can be used as a
FormattedValue. Previously, only
types which were able to represent a "full range"
implemented the trait. E.g.:
Option<ClockTime> implemented it, but
APIs which would accept any formatted value used a bind clause
V: Into<GenericFormattedValue> and the provided value was
forced into a
GenericFormattedValue in the function.
This change allows using a
V: FormattedValue bind instead.
In 95% of cases, this is all the function needs: no more
When a function needs a "full range" formatted value instead,
we can use the new trait
FormattedValueFullRange. The trait
FormattedValue uses an associated type
FullRange, in order
to refer to the full range type. This is needed when building
FormattedValue from a raw value.
Note: I'm not sure about the "full range" name here. This could also be "full scale", ...
Compatible Formatted Values
The second commit introduces the trait
This trait uses a
FormattedValue type parameter against which
we want to check format compatibility for
Self. This trait is
implemented on compatible combinations only.
SpecificFormattedValues, the implementation ensures type system
For checks involving at least one
GenericFormattedValue, checks are
performed at runtime via the function
try_into_checkedshould result to a no-op when the check can be performed at compilation.
- User can't use the argument as a
In some cases (e.g.
Segment<_>), the format to check is not enforced
by another argument but by a field of
Self. For those cases, the
try_into_checked_explicit performs the checks against an explicit
Format with as low an overhead as possible.
Note: I'm not 100% sure about the
try_into_checked* names here. Alternatives could be:
CheckedFormattedValue: shorter but I think we loose a bit of the semantic.
Conforming...: not sure if that would be more correct that
The following § is the initial proposal. It is left here so as to understand the discussion in the first comment.
A workaround could be using different types for
and binding them with the following clause:
where Start: SpecificFormattedValue, Stop: SpecificFormattedValue<FormattedValueType = <Start as SpecificFormattedValue>::FormattedValueType>
However, this would prevent the user from calling
seek with a
This commit decouples the types for functions with multiple formatted arguments. Format equivalence will no longer be enforced at compilation time, it will still be controlled at runtime thanks to the existing assertions.
The drawback is that we sometimes need to help the compiler with
type inference. See
basic-tutorial-13.rs as an example.
The commit also fixes
is said to be of
Time format in the documentation for
gst_message_new_step_done while it was bound to the format of
See also: gst-plugins-rs!797 (merged)