I need to store values with any of the range expression types in the same data structure (with their generic type fixed as T = usize). However, in creating the values that go into said data structure, I want to retain the language's range expression syntax. I'm specifically thinking of:
Range<usize>
RangeFrom<usize>
RangeFull
RangeInclusive<usize>
RangeTo<usize>
RangeToInclusive<usize>
and their associated double dot syntax (e.g. 2..5 as a way of creating a Range<usize>).
I'm OK with using dynamic dispatch for "anything that implements RangeBounds<usize>" here, but that doesn't work since RangeBounds<usize> is not object safe.
I'm also OK with a new enum type with all of the above as variants, but I don't see how to retain the range syntax in that case.
I would guess this is also easily doable with macros, but my macro skills are so bad that I'd really appreciate some hints if that is the best way.
That's pretty much the only way to do it. The way to retain the range syntax is to write a From<X> for RangeWrapper impl for each of the range types X.
That would allow you to write things like RangeWrapper::from(10..=42).
This is one way you could implement this via macros which resolve custom range-like syntax into different enum variants, but the From implementation @jjpe suggested is probably more interpretable.
May I dare ask why? I.e. what's your use case? Why is it not sufficient to accept anything that implements RangeBounds<usize> at the respective places?
This works if you eg have a function that takes a single range-like parameter. But if you need to store a multitude of range-like values, and be able to have them be heterogeneous in terms of their type (eg a Vec that contains a Range<usize> as well as a RangeFrom<usize>) then using the RangeBound trait won't work due to the dyn-unsafety.
This is a fantastic solution in the spirit of what I had imagined when asking the question. Thanks!!
FWIW: I went for jjpe's solution wrapped in a macro for building vectors or arrays of said values. That was also nice, but the one presented here by undefined.behavior is spot on what I had imagined when asking the question, so I'll definitely move to it.