Skip to content

Add std::ops::range::Bound::map_all #682

@IoaNNUwU

Description

@IoaNNUwU

Proposal

Problem statement

std and user crates have a lot of places with this pattern:

let start = match range.start_bound() {
    Bound::Included(n) => n,
    Bound::Excluded(n) => n + 1,
    Bound::Unbounded => 0,
}

Solution sketch

Add std::ops::range::Bound::map_all:

    /// Maps a `Bound<T>` to a `R` by applying a selected function `FnOnce(T) -> R` 
    /// to the matched contained value.
    pub fn map_all<R, I: FnOnce(T) -> R, E: FnOnce(T) -> R>(
        self,
        included: I,
        excluded: E,
        unbounded: R,
    ) -> R {
        match self {
            Bound::Included(x) => included(x),
            Bound::Excluded(x) => excluded(x),
            Bound::Unbounded => unbounded,
        }
    }

This will allow:

use std::range::Bound;

let start_bound: Bound<usize> = Bound::Included(0);
let start = start_bound.map_all(|i| i, |e| e + 1, 0);
assert_eq!(start, 0);

let start_bound: Bound<usize> = Bound::Excluded(0);
let start = start_bound.map_all(|i| i, |e| e + 1, 0);
assert_eq!(start, 1);

let start_bound: Bound<usize> = Bound::Unbounded;
let start = start_bound.map_all(|i| i, |e| e + 1, 0);
assert_eq!(start, 0);

Alternatives

  • alternative name map_idx

This function makes order of arguments less explicit. It may cause more bugs.

This feature is very small, niche and doesn't add much, but I think its reasonable to have something like this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions