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`.
getters/setters are already generated for the `Aggregator` base class
and the property in the subclass is not really needed here. It also
causes problems with trait resolution as the getter/setter functions
will exist twice.
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.