Skip to content

Implementing Input trait for bytes::Bytes #1838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
StephanvanSchaik opened this issue Mar 15, 2025 · 0 comments
Open

Implementing Input trait for bytes::Bytes #1838

StephanvanSchaik opened this issue Mar 15, 2025 · 0 comments

Comments

@StephanvanSchaik
Copy link

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

    // ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant