Non panicking version of &buf[start..end]

Hello,

To my knowledge there is no non-panicking equivalent of &buf[start..end] in the stdlib. Have I got this right? Would this be considered as a PR?

I asked on IRC and the first response turned out to have 2 bugs, which I guess is a datapoint in having it included in the stdlib: https://botbot.me/mozilla/rust/2015-09-21/?msg=50158708&page=10

(I wanted this today because I need to add some experimental code to an existing production process which cannot afford to fail. I want to reduce the chance of panicing in the new experimental code as much as possible.)

Thanks,

Phil

Should it return an Option<&[T]>? A slice with the available elements? Or a Result<&[T], &[T]> (where the error part is the available elements on overflow)?

I think it would be a good thing to have. We’re kind of working on adding it to odds.

In my limited experience these things are usually an error, e.g. some index arithmetic which can blow up in a way you hadn’t thought of, maybe because of a subsequent change.

In this case I’d probably want a Result<&[T], SliceError> so that I can take advantage of try!()

I tried doing so with the Index trait, but it requires returning &Self::Output, so it cannot return a Result, but a &Result, which won’t work here. So, I implemented an example without the trait, requiring a method call instead, like arr.slice(0..5).

enum SliceError {
    StartOutOfBounds,
    EndOutOfBounds,
    StartBiggerThanEnd
}

struct Wrap<'a, T: 'a>(&'a [T]);
impl<'a, T> Wrap<'a, T> {
    fn slice(&self, range: Range<usize>) -> Result<&[T], SliceError> {
        if range.start >= self.0.len() {
            Err(SliceError::StartOutOfBounds)
        } else if range.end > self.0.len() {
            Err(SliceError::EndOutOfBounds)
        } else if range.start > range.end {
            Err(SliceError::StartBiggerThanEnd)
        } else {
            unsafe {
                Ok(slice::from_raw_parts (
                    self.0.as_ptr().offset(range.start as isize),
                    range.end - range.start
                ))
            }
        }
    }
}

playground

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.