From 221cdee962772854d634aca800bf14c1c8a92c0b Mon Sep 17 00:00:00 2001 From: AngelOfSol Date: Wed, 21 Jul 2021 14:26:51 -0400 Subject: [PATCH] Genericizes the rest of the nom traits. --- src/lib.rs | 265 +++++++++++++++++++---------------------------------- 1 file changed, 96 insertions(+), 169 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ccced94..2416cad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -526,66 +526,42 @@ where } } -/// Implement nom::InputIter for a specific fragment type -/// -/// # Parameters -/// * `$fragment_type` - The LocatedSpan's `fragment` type -/// * `$item` - The type of the item being iterated (a reference for fragments of type `&[T]`). -/// * `$raw_item` - The raw type of the item being iterating (dereferenced type of $item for -/// `&[T]`, otherwise same as `$item`) -/// * `$iter` - The iterator type for `iter_indices()` -/// * `$iter_elem` - The iterator type for `iter_elements()` -/// -/// # Example of use -/// -/// NB: This example is an extract from the nom_locate source code. -/// -/// ```ignore -/// #[macro_use] -/// extern crate nom_locate; -/// -/// impl_input_iter!(&'a str, char, char, CharIndices<'a>, Chars<'a>); -/// impl_input_iter!(&'a [u8], &'a u8, u8, Enumerate>, -/// Iter<'a, Self::RawItem>); -/// ``` #[macro_export] +#[deprecated( + since = "3.1.0", + note = "this implementation has been generalized and no longer requires a macro" +)] macro_rules! impl_input_iter { - ($fragment_type:ty, $item:ty, $raw_item:ty, $iter:ty, $iter_elem:ty) => { - impl<'a, X> InputIter for LocatedSpan<$fragment_type, X> { - type Item = $item; - type Iter = $iter; - type IterElem = $iter_elem; - #[inline] - fn iter_indices(&self) -> Self::Iter { - self.fragment.iter_indices() - } - #[inline] - fn iter_elements(&self) -> Self::IterElem { - self.fragment.iter_elements() - } - #[inline] - fn position

(&self, predicate: P) -> Option - where - P: Fn(Self::Item) -> bool, - { - self.fragment.position(predicate) - } - #[inline] - fn slice_index(&self, count: usize) -> Result { - self.fragment.slice_index(count) - } - } - }; + () => {}; } -impl_input_iter!(&'a str, char, char, CharIndices<'a>, Chars<'a>); -impl_input_iter!( - &'a [u8], - u8, - u8, - Enumerate, - Copied> -); +impl<'a, T, X> InputIter for LocatedSpan +where + T: InputIter, +{ + type Item = T::Item; + type Iter = T::Iter; + type IterElem = T::IterElem; + #[inline] + fn iter_indices(&self) -> Self::Iter { + self.fragment.iter_indices() + } + #[inline] + fn iter_elements(&self) -> Self::IterElem { + self.fragment.iter_elements() + } + #[inline] + fn position

(&self, predicate: P) -> Option + where + P: Fn(Self::Item) -> bool, + { + self.fragment.position(predicate) + } + #[inline] + fn slice_index(&self, count: usize) -> Result { + self.fragment.slice_index(count) + } +} impl, B: Into>, X> Compare for LocatedSpan { #[inline(always)] @@ -608,106 +584,57 @@ macro_rules! impl_compare { ( $fragment_type:ty, $compare_to_type:ty ) => {}; } -/// Implement nom::Slice for a specific fragment type and range type. -/// -/// **You'd probably better use impl_`slice_ranges`**, -/// unless you use a specific Range. -/// -/// # Parameters -/// * `$fragment_type` - The LocatedSpan's `fragment` type -/// * `$range_type` - The range type to be use with `slice()`. -/// * `$can_return_self` - A bool-returning lambda telling whether we -/// can avoid creating a new `LocatedSpan`. If unsure, use `|_| false`. -/// -/// # Example of use -/// -/// NB: This example is an extract from the nom_locate source code. -/// -/// ````ignore -/// #[macro_use] -/// extern crate nom_locate; -/// -/// #[macro_export] -/// macro_rules! impl_slice_ranges { -/// ( $fragment_type:ty ) => { -/// impl_slice_range! {$fragment_type, Range, |_| false } -/// impl_slice_range! {$fragment_type, RangeTo, |_| false } -/// impl_slice_range! {$fragment_type, RangeFrom, |range:&RangeFrom| range.start == 0} -/// impl_slice_range! {$fragment_type, RangeFull, |_| true} -/// } -/// } -/// -/// ```` #[macro_export] +#[deprecated( + since = "3.1.0", + note = "this implementation has been generalized and no longer requires a macro" +)] macro_rules! impl_slice_range { - ( $fragment_type:ty, $range_type:ty, $can_return_self:expr ) => { - impl<'a, X: Clone> Slice<$range_type> for LocatedSpan<$fragment_type, X> { - fn slice(&self, range: $range_type) -> Self { - if $can_return_self(&range) { - return self.clone(); - } - let next_fragment = self.fragment.slice(range); - let consumed_len = self.fragment.offset(&next_fragment); - if consumed_len == 0 { - return LocatedSpan { - line: self.line, - offset: self.offset, - fragment: next_fragment, - extra: self.extra.clone(), - }; - } - - let consumed = self.fragment.slice(..consumed_len); - let next_offset = self.offset + consumed_len; - - let consumed_as_bytes = consumed.as_bytes(); - let iter = Memchr::new(b'\n', consumed_as_bytes); - let number_of_lines = iter.count() as u32; - let next_line = self.line + number_of_lines; - - LocatedSpan { - line: next_line, - offset: next_offset, - fragment: next_fragment, - extra: self.extra.clone(), - } - } - } - }; + ( $fragment_type:ty, $range_type:ty, $can_return_self:expr ) => {}; } -/// Implement nom::Slice for a specific fragment type and for these types of range: -/// * `Range` -/// * `RangeTo` -/// * `RangeFrom` -/// * `RangeFull` -/// -/// # Parameters -/// * `$fragment_type` - The LocatedSpan's `fragment` type -/// -/// # Example of use -/// -/// NB: This example is an extract from the nom_locate source code. -/// -/// ````ignore -/// #[macro_use] -/// extern crate nom_locate; -/// -/// impl_slice_ranges! {&'a str} -/// impl_slice_ranges! {&'a [u8]} -/// ```` #[macro_export] +#[deprecated( + since = "3.1.0", + note = "this implementation has been generalized and no longer requires a macro" +)] macro_rules! impl_slice_ranges { - ( $fragment_type:ty ) => { - impl_slice_range! {$fragment_type, Range, |_| false } - impl_slice_range! {$fragment_type, RangeTo, |_| false } - impl_slice_range! {$fragment_type, RangeFrom, |range:&RangeFrom| range.start == 0} - impl_slice_range! {$fragment_type, RangeFull, |_| true} - } + ( $fragment_type:ty ) => {}; } -impl_slice_ranges! {&'a str} -impl_slice_ranges! {&'a [u8]} +impl<'a, T, R, X: Clone> Slice for LocatedSpan +where + T: Slice + Offset + AsBytes + Slice>, +{ + fn slice(&self, range: R) -> Self { + let next_fragment = self.fragment.slice(range); + let consumed_len = self.fragment.offset(&next_fragment); + if consumed_len == 0 { + return LocatedSpan { + line: self.line, + offset: self.offset, + fragment: next_fragment, + extra: self.extra.clone(), + }; + } + + let consumed = self.fragment.slice(..consumed_len); + + let next_offset = self.offset + consumed_len; + + let consumed_as_bytes = consumed.as_bytes(); + let iter = Memchr::new(b'\n', consumed_as_bytes); + let number_of_lines = iter.count() as u32; + let next_line = self.line + number_of_lines; + + LocatedSpan { + line: next_line, + offset: next_offset, + fragment: next_fragment, + extra: self.extra.clone(), + } + } +} impl, Token, X> FindToken for LocatedSpan { fn find_token(&self, token: Token) -> bool { @@ -751,25 +678,11 @@ impl Display for LocatedSpan { } } -/// Implement nom::ExtendInto for a specific fragment type. -/// -/// # Parameters -/// * `$fragment_type` - The LocatedSpan's `fragment` type -/// * `$item` - The type of the item being iterated (a reference for fragments of type `&[T]`). -/// * `$extender` - The type of the Extended. -/// -/// # Example of use -/// -/// NB: This example is an extract from the nom_locate source code. -/// -/// ````ignore -/// #[macro_use] -/// extern crate nom_locate; -/// -/// impl_extend_into!(&'a str, char, String); -/// impl_extend_into!(&'a [u8], u8, Vec); -/// ```` #[macro_export] +#[deprecated( + since = "3.1.0", + note = "this implementation has been generalized and no longer requires a macro" +)] macro_rules! impl_extend_into { ($fragment_type:ty, $item:ty, $extender:ty) => { impl<'a, X> ExtendInto for LocatedSpan<$fragment_type, X> { @@ -790,9 +703,23 @@ macro_rules! impl_extend_into { } #[cfg(feature = "alloc")] -impl_extend_into!(&'a str, char, String); -#[cfg(feature = "alloc")] -impl_extend_into!(&'a [u8], u8, Vec); +impl<'a, T, X> ExtendInto for LocatedSpan +where + T: ExtendInto, +{ + type Item = T::Item; + type Extender = T::Extender; + + #[inline] + fn new_builder(&self) -> Self::Extender { + self.fragment.new_builder() + } + + #[inline] + fn extend_into(&self, acc: &mut Self::Extender) { + self.fragment.extend_into(acc) + } +} #[cfg(feature = "std")] #[macro_export]