Skip to content

Implementing Input trait for bytes::Bytes #1838

Open
@StephanvanSchaik

Description

@StephanvanSchaik

It would be useful to be able to use nom with the Bytes type from the bytes and the types from other similar crates such as arc-slice and byteview. While using these types does not speed up parsing with nom itself, they do help significantly in the post-processing stage in achieving zero-copy by avoiding unnecessary allocations as .clone() is much cheaper due to it incrementing an atomic reference counter and taking a subslice, rather than allocating more memory and copying over the subslice.

Unfortunately, it is not entirely clear to me how to implement the Input trait (and perhaps other traits) for such a type due to the lifetime used in type Iter = Copied<Iter<'a, u8>>; whereas Bytes lacks a lifetime (since it is akin to Arc<[u8]> rather than &'a u8). Implementation is rather trivial other than for the lifetime issue, but I am not sure how to proceed with fixing the lifetime issue itself:

impl Input for bytes::Bytes {
    type Item = u8;
    type Iter = Copied<Iter<'_, u8>>;
    type IterIndices = Enumerate<Self::Iter>;

    fn input_len(&self) -> usize {
        self.len()
    }

    #[inline]
    fn take(&self, index: usize) -> Self {
        self.slice(..index)
    }

    fn take_from(&self, index: usize) -> Self {
        self.slice(index..)
    }

    #[inline]
    fn take_split(&self, index: usize) -> (Self, Self) {
        let prefix = self.take(index);
        let suffix = self.take_from(index);

        (suffix, prefix)
    }

    #[inline]
    fn position<P>(&self, predicate: P) -> Option<usize>
    where
        P: Fn(Self::Item) -> bool,
    {
        self.iter().position(|b| predicate(*b))
    }

    #[inline]
    fn iter_elements(&self) -> Self::Iter {
        self.iter().copied()
    }

    // ...
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions