o3 0.34.4

shared-nothing primitives
Documentation
use std::num::NonZero;

use crate::{buffer, buffer::segments::scatter};
/// Exact-progress traversal over one immutable scattered source.
///
/// # Safety
/// Progress, cap, remaining length, and `'data` must all be exact.
pub unsafe trait Scatter<'data> {
    fn remaining(&self) -> usize;

    /// Advances to an admitted byte offset in this exact cursor.
    fn seek(mut self, offset: usize) -> Option<Self>
    where
        Self: Sized,
    {
        if offset > self.remaining() {
            return None;
        }
        scatter::Take::new(&mut self, offset).finish();
        Some(self)
    }

    /// Borrows at most the requested number of remaining bytes.
    fn take_bytes(&mut self, limit: usize) -> scatter::Take<'_, 'data, Self>
    where
        Self: Sized,
    {
        scatter::Take::new(self, limit)
    }

    /// Advances by a nonempty prefix of the admitted remaining bytes.
    ///
    /// # Safety
    /// `cap <= self.remaining()` and `cap <= MAX`; output advances exactly `1..=cap` bytes.
    unsafe fn advance<const MAX: usize>(
        &mut self,
        cap: NonZero<usize>,
    ) -> buffer::raw::Chunk<'data, MAX>;
}

// SAFETY: the exclusive borrow delegates every observation and transition to
// the same exact cursor while preventing independent advancement of its state.
unsafe impl<'data, C: Scatter<'data> + ?Sized> Scatter<'data> for &mut C {
    fn remaining(&self) -> usize {
        C::remaining(self)
    }

    unsafe fn advance<const MAX: usize>(
        &mut self,
        cap: NonZero<usize>,
    ) -> buffer::raw::Chunk<'data, MAX> {
        // SAFETY: the borrowed cursor has the exact state specified by the caller.
        unsafe { C::advance(self, cap) }
    }
}

// SAFETY: the slice lifetime is the source lifetime, and advancing can only
// replace it with an exact suffix of the same allocation.
unsafe impl<'data> Scatter<'data> for &'data [u8] {
    fn remaining(&self) -> usize {
        self.len()
    }

    unsafe fn advance<const MAX: usize>(
        &mut self,
        cap: NonZero<usize>,
    ) -> buffer::raw::Chunk<'data, MAX> {
        // SAFETY: the caller proves cap <= this slice's length.
        let (bytes, suffix) = unsafe { self.split_at_unchecked(cap.get()) };
        *self = suffix;
        // SAFETY: nonzero cap <= MAX proves a nonempty bounded prefix,
        // and bytes retains the source slice lifetime.
        unsafe { buffer::raw::Chunk::new(bytes) }
    }
}

mod queues;