Idea/proposal: Total_duration enum (unknown/max/guarenteed)
Idea by @The0x539 https://github.com/RustAudio/rodio/issues/626#issuecomment-2661094585. Currently infinite sources will return None for total_duration, when paired with a TakeDuration you still get None. Another place we can do better is skippable. Right now a skippable will pass on the total_duration of what it wraps. Because the source can be skipped at any point there is no guarentee it will actually play for that length.
To address these issues we can put extra information in the total_duration result:
enum SourceDuration {
Max(Duration),
Guarenteed(Duration),
Infinite,
Unknown,
}
We could provide methods to turn this into an option returning Duration::MAX for Infinite. We could call that method known. We could also provide a map, is_known and maybe an unwrap_or.
A far simpler alternative to this proposal would be making infinite sources return Duration::MAX.
By contract, Iterator::size_hint returns None for its upper bound when it would exceed usize::MAX (like infinity). Not saying that Source::total_duration needs to follow that, but there's some appeal to following that convention.
A far simpler alternative to this proposal would be making infinite sources return
Duration::MAX.
While not correct formally, and the perfectionist in my doesn't like that 😆 I could get over that. Because honestly, which source is 584.942.417.355 years or greater in length?
Another option would be to have a Source::is_infinite to discern infinite streams or looped sources.
By contract,
Iterator::size_hintreturnsNonefor its upper bound when it would exceedusize::MAX(like infinity). Not saying thatSource::total_durationneeds to follow that, but there's some appeal to following that convention.
The problem with that convention is that it does not discern infinity from unknown. For iterators that does not matter, but for us it does since we do a min(Unknown | Infinite | Concretevalue, ConcreteValue) in TakeDuration.
Because honestly, which source is 584.942.417.355 years or greater in length?
very valid, using Duration::MAX makes it easier to implement too, no need to match. Min(Infinity, ConcreteValue) is implemented as Min(MAX, ConcreteValue).