#1838·nom

Implementing Input trait for bytes::Bytes

Author: StephanvanSchaikCreated Mar 15, 2025Updated Mar 23, 2026

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()
    }

    // ...
}