Skip to content

ExactlyOneError should not iterate itself #1047

Description

@phimuemue

Follow-up to #1046

I'm pondering whether

fn exactly_one(mut self) -> Result<Self::Item, ExactlyOneError<Self>>

should rather be

fn exactly_one(&mut self) -> Result<Self::Item, ExactlyOneError<Self::Item>>

and ExactlyOneError should contain an Option<[Self::Item; 2]>, so that the user can inspect the first two elements, and simply re-use the iterator afterwards, if they want to. (Similar to our all_equal_value.)

I think this is better, because at the moment we must specialize each and every function/trait (e.g. ExactSizeIterator, DoubleEndedIterator) to exploit the underlying iterator's specializations.

With my proposal, the user could still do this:

match iter.exactly_one() {
 Ok(value) => do_stuff_with(value),
 Err(None) => iterator_was_empty(),
 Err(Some(values)) => {
  // process *all* elements of the original iterator:
  values.chain(iter).for_each(...);
 }
}

or - terse -:

match iter.exactly_one() {
 Ok(value) => do_stuff_with(value),
 Err(optional_2_values) => {
  // process *all* elements of the original iterator:
  optional_2_values.into_iter().flatten().chain(iter).for_each(...);
 }
}

That is, we do not lose functionality, but the callers profit all specializations given by std.

Note: From my experience, re-visiting all elements of the original iterator is very rare. In most cases, it only matters if exactly_one worked or not, and if it did not work, the elements themselves are not relevant.

Following similar reasoning, I advocate for fn at_most_one(&mut self) -> Result<Option<Item>, AtMostOneError<Self::Item>> where AtMostOneError wraps a [Self::Item; 2].

@jswrenn I'd appreciate your opinion on this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions