🏡 index : ~doyle/nom-bytes.git

author Jordan Doyle <jordan@doyle.la> 2021-01-30 22:18:28.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-01-30 23:27:04.0 +00:00:00
commit
7e44afde2e53f447fc9c77297eb513186b8fb0da [patch]
tree
d8ea2f27a65fe6ed95c50645f1bf9420d7c7741c
download
7e44afde2e53f447fc9c77297eb513186b8fb0da.tar.gz

Initial commit



Diff

 .gitignore |   2 +-
 Cargo.toml |  11 ++++++-
 LICENSE    |  13 ++++++++-
 src/lib.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 133 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..96ef6c0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
/target
Cargo.lock
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..8ec0c34
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,11 @@
[package]
name = "nom-bytes"
version = "0.1.0"
authors = ["Jordan Doyle <jordan@doyle.la>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nom = "6.1"
bytes = "1.0"
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..5c93f45
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..8b09f94
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,107 @@
use std::{iter::Enumerate, ops::Deref};

use nom::Needed;

/// A wrapper type for `bytes::Bytes` that implements all the traits `nom` needs
/// to be able to parse the inner value.
#[derive(Debug, Clone)]
pub struct BytesWrapper(bytes::Bytes);

impl Deref for BytesWrapper {
    type Target = bytes::Bytes;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Into<bytes::Bytes> for BytesWrapper {
    fn into(self) -> bytes::Bytes {
        self.0
    }
}

impl From<bytes::Bytes> for BytesWrapper {
    fn from(bytes: bytes::Bytes) -> Self {
        Self(bytes)
    }
}

impl nom::InputTake for BytesWrapper {
    fn take(&self, count: usize) -> Self {
        BytesWrapper::from(self.0.slice(0..count))
    }

    fn take_split(&self, count: usize) -> (Self, Self) {
        (
            BytesWrapper::from(self.0.slice(count..)),
            BytesWrapper::from(self.0.slice(0..count)),
        )
    }
}

impl nom::FindSubstring<&[u8]> for BytesWrapper {
    fn find_substring(&self, substr: &[u8]) -> Option<usize> {
        (&self.0[..]).find_substring(substr)
    }
}

impl nom::FindSubstring<&str> for BytesWrapper {
    fn find_substring(&self, substr: &str) -> Option<usize> {
        (&self.0[..]).find_substring(substr)
    }
}

impl nom::InputLength for BytesWrapper {
    fn input_len(&self) -> usize {
        self.0.len()
    }
}

impl<'a> nom::InputIter for BytesWrapper {
    type Item = u8;
    type Iter = Enumerate<Self::IterElem>;
    type IterElem = bytes::buf::IntoIter<bytes::Bytes>;

    fn iter_elements(&self) -> Self::IterElem {
        self.0.clone().into_iter()
    }

    fn iter_indices(&self) -> Self::Iter {
        self.iter_elements().enumerate()
    }

    fn position<P>(&self, predicate: P) -> Option<usize>
    where
        P: Fn(Self::Item) -> bool,
    {
        (&self.0[..]).position(predicate)
    }

    fn slice_index(&self, count: usize) -> Result<usize, Needed> {
        (&self.0[..]).slice_index(count)
    }
}

impl nom::UnspecializedInput for BytesWrapper {}

#[cfg(test)]
mod tests {
    use bytes::Bytes;
    use nom::bytes::complete::*;

    use crate::BytesWrapper;

    #[test]
    fn it_works() {
        let input = BytesWrapper::from(Bytes::from_static(
            b"this is my cool input, please don't copy from me!",
        ));

        let (rest, v) =
            take_till::<_, _, nom::error::Error<BytesWrapper>>(|v| v == b',')(input).unwrap();

        assert_eq!(&v[..], b"this is my cool input");
        assert_eq!(&rest[..], b", please don't copy from me!");
    }
}