diff --git a/src/lib.rs b/src/lib.rs index 5f850e9..f9259b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,6 +139,13 @@ pub struct LocatedSpan { pub extra: X, } +impl core::ops::Deref for LocatedSpan { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.fragment + } +} + impl LocatedSpan { /// Create a span for a particular input with default `offset` and /// `line` values and empty extra data. @@ -516,68 +523,26 @@ impl_input_iter!( Map, fn(&u8) -> u8> ); -/// Implement nom::Compare for a specific fragment type. -/// -/// # Parameters -/// * `$fragment_type` - The LocatedSpan's `fragment` type -/// * `$compare_to_type` - The type to be comparable to `LocatedSpan<$fragment_type, X>` -/// -/// # Example of use -/// -/// NB: This example is an extract from the nom_locate source code. -/// -/// ````ignore -/// #[macro_use] -/// extern crate nom_locate; -/// impl_compare!(&'b str, &'a str); -/// impl_compare!(&'b [u8], &'a [u8]); -/// impl_compare!(&'b [u8], &'a str); -/// ```` -#[macro_export] -macro_rules! impl_compare { - ( $fragment_type:ty, $compare_to_type:ty ) => { - impl<'a, 'b, X> Compare<$compare_to_type> for LocatedSpan<$fragment_type, X> { - #[inline(always)] - fn compare(&self, t: $compare_to_type) -> CompareResult { - self.fragment.compare(t) - } - - #[inline(always)] - fn compare_no_case(&self, t: $compare_to_type) -> CompareResult { - self.fragment.compare_no_case(t) - } - } - }; -} - -impl_compare!(&'b str, &'a str); -impl_compare!(&'b [u8], &'a [u8]); -impl_compare!(&'b [u8], &'a str); - -impl, B, X, Y> Compare> for LocatedSpan { +impl, B: Into>, X> Compare for LocatedSpan { #[inline(always)] - fn compare(&self, t: LocatedSpan) -> CompareResult { - self.fragment.compare(t.fragment) + fn compare(&self, t: B) -> CompareResult { + self.fragment.compare(t.into().fragment) } #[inline(always)] - fn compare_no_case(&self, t: LocatedSpan) -> CompareResult { - self.fragment.compare_no_case(t.fragment) + fn compare_no_case(&self, t: B) -> CompareResult { + self.fragment.compare_no_case(t.into().fragment) } } -// TODO(future): replace impl_compare! with below default specialization? -// default impl, B, X> Compare for LocatedSpan { -// #[inline(always)] -// fn compare(&self, t: B) -> CompareResult { -// self.fragment.compare(t) -// } -// -// #[inline(always)] -// fn compare_no_case(&self, t: B) -> CompareResult { -// self.fragment.compare_no_case(t) -// } -// } +#[macro_export] +#[deprecated( + since = "2.1.0", + note = "this implementation has been generalized and no longer requires a macro" +)] +macro_rules! impl_compare { + ( $fragment_type:ty, $compare_to_type:ty ) => {}; +} /// Implement nom::Slice for a specific fragment type and range type. /// @@ -767,28 +732,15 @@ impl_extend_into!(&'a [u8], u8, Vec); #[cfg(feature = "std")] #[macro_export] +#[deprecated( + since = "2.1.0", + note = "this implementation has been generalized and no longer requires a macro" +)] macro_rules! impl_hex_display { - ($fragment_type:ty) => { - #[cfg(feature = "alloc")] - impl<'a, X> nom::HexDisplay for LocatedSpan<$fragment_type, X> { - fn to_hex(&self, chunk_size: usize) -> String { - self.fragment.to_hex(chunk_size) - } - - fn to_hex_from(&self, chunk_size: usize, from: usize) -> String { - self.fragment.to_hex_from(chunk_size, from) - } - } - }; + ($fragment_type:ty) => {}; } -#[cfg(feature = "std")] -impl_hex_display!(&'a str); -#[cfg(feature = "std")] -impl_hex_display!(&'a [u8]); - /// Capture the position of the current fragment - #[macro_export] macro_rules! position { ($input:expr,) => { diff --git a/src/tests.rs b/src/tests.rs index 17451f6..537b53e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -392,3 +392,25 @@ fn it_should_capture_position() { assert_eq!(s.line, 2); assert_eq!(t, "def"); } + +#[test] +fn it_should_deref_to_fragment() { + let input = &"foobar"[..]; + assert_eq!(*StrSpanEx::new_extra(input, "extra"), input); + let input = &b"foobar"[..]; + assert_eq!(*BytesSpanEx::new_extra(input, "extra"), input); +} + +#[cfg(feature = "std")] +#[test] +fn it_should_display_hex() { + use nom::HexDisplay; + assert_eq!( + StrSpan::new(&"abc"[..]).to_hex(4), + "00000000\t61 62 63 \tabc\n".to_owned() + ); + assert_eq!( + BytesSpanEx::new_extra(&b"abc"[..], "extra").to_hex(4), + "00000000\t61 62 63 \tabc\n".to_owned() + ); +}