-
Notifications
You must be signed in to change notification settings - Fork 139
Description
Progress
- Implement
SplitAttrait - Cut alpha release
- Implement @kupiakos ' suggestion below
- Cut a new alpha release
- Test in Fuchsia
- Cut normal release
Given a &[T], Rust supports creating a new &[T] referring to a subset of the original referent, and also supports splitting into two non-overlapping &[T]s that, together, cover the original referent. To my knowledge, this is not supported for slice DSTs.
We could add APIs for these slicing operations to KnownLayout<PointerMetadata = usize>.
One use case for this design would be to support packet formats with explicit length fields - it would be a possibly lighter-weight way of supporting #1289 without requiring solving the general problem described in that issue.
Suggestion thanks to @kupiakos: Currently the API looks like this:
pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
fn split_at(&self, l_len: usize) -> Option<(&Self, &[Self::Elem])>
where Self: Immutable { ... }
fn split_at_mut(
&mut self,
l_len: usize,
) -> Option<(&mut Self, &mut [Self::Elem])> { ... }
}We want to make two changes:
- Support cases in which there is guaranteed to be no padding (thanks to
IntoBytes) - Support shared references when
Self: !Immutable, adding padding overlap as an error condition
We can support these uniformly like so:
pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
fn split_at(&self, l_len: usize) -> Result<(&Self, &[Self::Elem]), SplitAtError<&'_ Self>> { ... }
fn split_at_mut(
&mut self,
l_len: usize,
) -> Result<(&mut Self, &mut [Self::Elem]), SplitAtError<&'_ mut Self>> { ... }
}
pub struct OutOfBoundsError;
pub struct PaddingOverlapError;
pub enum SplitAtError<Src, PaddingOverlap = PaddingOverlapError> {
OutOfBounds(OutOfBoundsError),
PaddingOverlap(PaddingOverlap),
}We can then provide methods which convert SplitAtError<_, PaddingOverlapError> to SplitAtError<_, !> with certain bounds:
SplitAtError<&T, PaddingOverlapError> -> SplitAtError<&T, !>where either:T: ImmutableT: IntoBytes
SplitAtError<&mut T, PaddingOverlapError> -> SplitAtError<&mut T, !>whereT: IntoBytes