Skip to content

Commit 807d00f

Browse files
authored
improve range bound ergonomics (#289)
1 parent 430fd44 commit 807d00f

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Improved ergonomics of indexing into UnsizedList by allowing direct use of RangeBounds instead of wrapping in a tuple. (#285)
13+
1014
## [0.26.3] - 2025-10-28
1115

12-
### Fixed
16+
### Fixed
1317

1418
- Fixed errors in cli template caused due to breaking changes made in star_frame (#283)
1519

star_frame/src/unsize/impls/list.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -265,27 +265,41 @@ where
265265
};
266266
(start, end)
267267
}
268-
impl<T, L, R> Index<(R,)> for List<T, L>
268+
269+
/// This wraps the [`std::ops::RangeBounds`] trait to get around orphan rule issues.
270+
///
271+
/// Without this, we'd run into the following:
272+
/// upstream crates may add a new impl of trait `std::ops::RangeBounds<usize>` for type `usize` in future versions
273+
trait GetBounds: RangeBounds<usize> {}
274+
275+
impl GetBounds for std::ops::RangeFull {}
276+
impl GetBounds for std::ops::Range<usize> {}
277+
impl GetBounds for std::ops::RangeFrom<usize> {}
278+
impl GetBounds for std::ops::RangeTo<usize> {}
279+
impl GetBounds for std::ops::RangeInclusive<usize> {}
280+
impl GetBounds for std::ops::RangeToInclusive<usize> {}
281+
282+
impl<T, L, R> Index<R> for List<T, L>
269283
where
270284
T: CheckedBitPattern + NoUninit + Align1,
271285
L: ListLength,
272-
R: RangeBounds<usize>,
286+
R: GetBounds,
273287
{
274288
type Output = [T];
275289

276-
fn index(&self, index: (R,)) -> &Self::Output {
277-
let (start, end) = get_bounds(self, index.0);
290+
fn index(&self, index: R) -> &Self::Output {
291+
let (start, end) = get_bounds(self, index);
278292
checked::try_cast_slice(&self.bytes[start..end]).expect("Invalid data for range")
279293
}
280294
}
281-
impl<T, L, R> IndexMut<(R,)> for List<T, L>
295+
impl<T, L, R> IndexMut<R> for List<T, L>
282296
where
283297
T: CheckedBitPattern + NoUninit + Align1,
284298
L: ListLength,
285-
R: RangeBounds<usize>,
299+
R: GetBounds,
286300
{
287-
fn index_mut(&mut self, index: (R,)) -> &mut Self::Output {
288-
let (start, end) = get_bounds(self, index.0);
301+
fn index_mut(&mut self, index: R) -> &mut Self::Output {
302+
let (start, end) = get_bounds(self, index);
289303
checked::try_cast_slice_mut(&mut self.bytes[start..end]).expect("Invalid data for range")
290304
}
291305
}

0 commit comments

Comments
 (0)