From 7e44afde2e53f447fc9c77297eb513186b8fb0da Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 30 Jan 2021 22:18:28 +0000 Subject: [PATCH] Initial commit --- .gitignore | 2 ++ Cargo.toml | 11 +++++++++++ LICENSE | 13 +++++++++++++ src/lib.rs | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 src/lib.rs 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 "] +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 + + 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 for BytesWrapper { + fn into(self) -> bytes::Bytes { + self.0 + } +} + +impl From 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 { + (&self.0[..]).find_substring(substr) + } +} + +impl nom::FindSubstring<&str> for BytesWrapper { + fn find_substring(&self, substr: &str) -> Option { + (&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; + type IterElem = bytes::buf::IntoIter; + + fn iter_elements(&self) -> Self::IterElem { + self.0.clone().into_iter() + } + + fn iter_indices(&self) -> Self::Iter { + self.iter_elements().enumerate() + } + + fn position

(&self, predicate: P) -> Option + where + P: Fn(Self::Item) -> bool, + { + (&self.0[..]).position(predicate) + } + + fn slice_index(&self, count: usize) -> Result { + (&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>(|v| v == b',')(input).unwrap(); + + assert_eq!(&v[..], b"this is my cool input"); + assert_eq!(&rest[..], b", please don't copy from me!"); + } +} -- libgit2 1.7.2