Polymorphic range contains()

I want to provide the user with the ability to select data that fall within certain ranges of values. It should be possible to provide both upper and lower bounds simultaneously, or bound the selection on just one side, leaving the other end unbounded.

The standard Rust range syntax (lo..hi) and the related contains() function seem closely related to this idea, so I tried basing my solution on those.

The std::ops::RangeBounds trait turns out not to be object-safe, so it seems impossible to create functions which pass around dynamically-polymorphic values representing ranges.

Before I give up on reusing the standard range utilities and roll my own, could you suggest how to avoid reinventing this wheel?

In terms of code, I'd like to write a function which contains something like

.filter(|value| range.contains(value))

where range is something morally equivalent to any of

  • lo..hi
  • ..hi
  • lo..
  • ..

and is passed in to the function.

The problem is that these 4 examples correspond to 4 different types (rather than variants of the same type) which implement the non-object-safe trait std::ops::RangeBounds.

[Additionally, I'd like the user to be able to specify these on the CLI. Can I avoid having to write my own parser for the a..b syntax? I have quickly hacked together a parser that seems to work, but it would be better to use something more robust, if already available.]

The RangeBounds trait is implemented for (Bound<T>, Bound<T>) where Bound is the following enum:

pub enum Bound<T> {
    Included(T),
    Excluded(T),
    Unbounded,
}

This should let you write any range you want using a single type.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.