o3/buffer/bytes/scope/
view.rs1use std::{marker, num, ops};
2
3use crate::buffer::{bytes::scope, is_within, storage::range, write::consume};
4
5#[derive(Clone, Copy)]
7pub struct View<'a, 'id> {
8 pub(in crate::buffer::bytes::scope) bytes: &'a [u8],
9 pub(in crate::buffer::bytes::scope) brand: marker::PhantomData<*mut &'id ()>,
10}
11
12impl<'a, 'id> View<'a, 'id> {
13 pub const fn as_slice(&self) -> &'a [u8] {
14 self.bytes
15 }
16
17 pub fn get<P: scope::raw::Select<'id>>(self, proof: P) -> (&'a [u8], scope::Range<'id>) {
19 let bounds = proof.bounds();
20 let bytes = unsafe { self.bytes.get_unchecked(bounds.clone()) };
23 (bytes, scope::Range::new(self, bounds))
24 }
25
26 pub fn try_get(self, bounds: ops::Range<usize>) -> Result<scope::Range<'id>, range::Error> {
27 if !is_within(&bounds, self.bytes.len()) {
28 return Err(range::Error::new(bounds, self.bytes.len()));
29 }
30 Ok(scope::Range::new(self, bounds))
31 }
32
33 pub fn try_rsplit<const N: usize>(
34 self,
35 ) -> Result<(&'a [u8; N], scope::Range<'id>), consume::Error> {
36 let Some((prefix, tail)) = self.bytes.split_last_chunk::<N>() else {
37 return Err(consume::Error::new(
38 num::NonZero::<usize>::MIN.saturating_add(N.saturating_sub(1)),
39 self.bytes.len(),
40 ));
41 };
42 Ok((tail, scope::Range::new(self, 0..prefix.len())))
43 }
44}
45
46impl<'id> scope::Source for View<'_, 'id> {
47 type Selection = scope::Range<'id>;
48
49 fn select(self, bytes: &[u8]) -> Option<Self::Selection> {
50 Some(scope::Range::new(
51 self,
52 self.bytes.subslice_range(bytes)?.into(),
53 ))
54 }
55}
56
57const _: () = assert!(size_of::<View<'static, 'static>>() == 2 * size_of::<usize>());