From 75504f3d007f11d0d2c34b7d736777b25dc71135 Mon Sep 17 00:00:00 2001 From: Alextopher Date: Wed, 3 Aug 2022 08:46:07 -0400 Subject: [PATCH 1/6] Span::get --- pest/src/span.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/pest/src/span.rs b/pest/src/span.rs index 9f375fa3..1d30e675 100644 --- a/pest/src/span.rs +++ b/pest/src/span.rs @@ -61,6 +61,41 @@ impl<'i> Span<'i> { } } + /// Attempts to create a new span within the bounds of `this` span. Will return `None` if + /// `range` does not fit within `this`. + /// + /// ``` + /// use pest::Span; + /// let input = "Hello World!"; + /// let world = Span::new(input, 6, input.len()).unwrap(); + /// let orl = world.get(1..=3); + /// assert!(orl.is_some()); + /// assert_eq!(orl.unwrap().as_str(), "orl"); + /// ``` + /// + /// # Examples + pub fn get(&self, range: impl std::ops::RangeBounds) -> Option> { + let start = match range.start_bound() { + std::ops::Bound::Included(offset) => *offset, + std::ops::Bound::Excluded(offset) => *offset + 1, + std::ops::Bound::Unbounded => 0, + }; + let end = match range.end_bound() { + std::ops::Bound::Included(offset) => *offset + 1, + std::ops::Bound::Excluded(offset) => *offset, + std::ops::Bound::Unbounded => self.as_str().len(), + }; + + match self.as_str().get(start..end) { + Some(_) => Some(Span { + input: self.input, + start: self.start + start, + end: self.start + end, + }), + None => None, + } + } + /// Returns the `Span`'s start byte position as a `usize`. /// /// # Examples @@ -264,6 +299,46 @@ mod tests { use alloc::borrow::ToOwned; use alloc::vec::Vec; + #[test] + fn get() { + let input = "abc123abc"; + let span = Span::new(input, 3, input.len()).unwrap(); + assert_eq!(span.as_str(), "123abc"); + assert_eq!(span.input, input); + + let span1 = span.get(..=2); + assert!(span1.is_some()); + assert_eq!(span1.unwrap().input, input); + assert_eq!(span1.unwrap().as_str(), "123"); + + let span2 = span.get(..); + assert!(span2.is_some()); + assert_eq!(span2.unwrap().input, input); + assert_eq!(span2.unwrap().as_str(), "123abc"); + + let span3 = span.get(3..); + assert!(span3.is_some()); + assert_eq!(span3.unwrap().input, input); + assert_eq!(span3.unwrap().as_str(), "abc"); + + let span4 = span.get(0..0); + assert!(span4.is_some()); + assert_eq!(span4.unwrap().input, input); + assert_eq!(span4.unwrap().as_str(), ""); + } + + #[test] + fn get_fails() { + let input = "abc"; + let span = Span::new(input, 0, input.len()).unwrap(); + + let span1 = span.get(0..100); + assert!(span1.is_none()); + + let span2 = span.get(100..200); + assert!(span2.is_none()); + } + #[test] fn span_comp() { let input = "abc\ndef\nghi"; From 03c89d8e863dea8db769e9503cfe388d18e34880 Mon Sep 17 00:00:00 2001 From: Alextopher Date: Wed, 3 Aug 2022 09:04:22 -0400 Subject: [PATCH 2/6] chore: use @tangmi more succinct description --- pest/src/span.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pest/src/span.rs b/pest/src/span.rs index 1d30e675..7f8a2005 100644 --- a/pest/src/span.rs +++ b/pest/src/span.rs @@ -61,8 +61,7 @@ impl<'i> Span<'i> { } } - /// Attempts to create a new span within the bounds of `this` span. Will return `None` if - /// `range` does not fit within `this`. + /// Attempts to create a new span based on a sub-range. /// /// ``` /// use pest::Span; From dc4688bd1b1c3a49436275bc9cc64e7964c1a329 Mon Sep 17 00:00:00 2001 From: Alextopher Date: Wed, 3 Aug 2022 09:39:09 -0400 Subject: [PATCH 3/6] Fix: use core::ops::RangeBounds --- pest/src/span.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pest/src/span.rs b/pest/src/span.rs index 7f8a2005..13f79ae5 100644 --- a/pest/src/span.rs +++ b/pest/src/span.rs @@ -9,6 +9,7 @@ use core::fmt; use core::hash::{Hash, Hasher}; +use core::ops::RangeBounds; use core::ptr; use core::str; @@ -73,7 +74,7 @@ impl<'i> Span<'i> { /// ``` /// /// # Examples - pub fn get(&self, range: impl std::ops::RangeBounds) -> Option> { + pub fn get(&self, range: impl RangeBounds) -> Option> { let start = match range.start_bound() { std::ops::Bound::Included(offset) => *offset, std::ops::Bound::Excluded(offset) => *offset + 1, From eb7b73839e48714e4b44646199fe8500af634d6e Mon Sep 17 00:00:00 2001 From: Alextopher Date: Wed, 3 Aug 2022 09:41:46 -0400 Subject: [PATCH 4/6] nit: use .map over an option instead of matching --- pest/src/span.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/pest/src/span.rs b/pest/src/span.rs index 13f79ae5..84a11fdd 100644 --- a/pest/src/span.rs +++ b/pest/src/span.rs @@ -86,14 +86,11 @@ impl<'i> Span<'i> { std::ops::Bound::Unbounded => self.as_str().len(), }; - match self.as_str().get(start..end) { - Some(_) => Some(Span { - input: self.input, - start: self.start + start, - end: self.start + end, - }), - None => None, - } + self.as_str().get(start..end).map(|_| Span { + input: self.input, + start: self.start + start, + end: self.start + end, + }) } /// Returns the `Span`'s start byte position as a `usize`. From 95b28d6e04ad61212af4312ca52875ebc302439e Mon Sep 17 00:00:00 2001 From: Alextopher Date: Wed, 3 Aug 2022 10:21:36 -0400 Subject: [PATCH 5/6] Fix: Actually? remove std --- pest/Cargo.toml | 2 +- pest/src/span.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pest/Cargo.toml b/pest/Cargo.toml index 7c17c96a..5794756e 100644 --- a/pest/Cargo.toml +++ b/pest/Cargo.toml @@ -14,7 +14,7 @@ readme = "_README.md" rust-version = "1.56" [features] -default = ["std"] +# default = ["std"] # Implements `std::error::Error` for the `Error` type std = ["ucd-trie/std", "thiserror"] # Enables the `to_json` function for `Pair` and `Pairs` diff --git a/pest/src/span.rs b/pest/src/span.rs index 84a11fdd..15fdb943 100644 --- a/pest/src/span.rs +++ b/pest/src/span.rs @@ -9,7 +9,7 @@ use core::fmt; use core::hash::{Hash, Hasher}; -use core::ops::RangeBounds; +use core::ops::{Bound, RangeBounds}; use core::ptr; use core::str; @@ -76,14 +76,14 @@ impl<'i> Span<'i> { /// # Examples pub fn get(&self, range: impl RangeBounds) -> Option> { let start = match range.start_bound() { - std::ops::Bound::Included(offset) => *offset, - std::ops::Bound::Excluded(offset) => *offset + 1, - std::ops::Bound::Unbounded => 0, + Bound::Included(offset) => *offset, + Bound::Excluded(offset) => *offset + 1, + Bound::Unbounded => 0, }; let end = match range.end_bound() { - std::ops::Bound::Included(offset) => *offset + 1, - std::ops::Bound::Excluded(offset) => *offset, - std::ops::Bound::Unbounded => self.as_str().len(), + Bound::Included(offset) => *offset + 1, + Bound::Excluded(offset) => *offset, + Bound::Unbounded => self.as_str().len(), }; self.as_str().get(start..end).map(|_| Span { From 5c6a613c504546c9417a06ec8144244a3e72a9c4 Mon Sep 17 00:00:00 2001 From: Alextopher Date: Wed, 3 Aug 2022 10:22:12 -0400 Subject: [PATCH 6/6] revert bad change in cargo.toml --- pest/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pest/Cargo.toml b/pest/Cargo.toml index 5794756e..7c17c96a 100644 --- a/pest/Cargo.toml +++ b/pest/Cargo.toml @@ -14,7 +14,7 @@ readme = "_README.md" rust-version = "1.56" [features] -# default = ["std"] +default = ["std"] # Implements `std::error::Error` for the `Error` type std = ["ucd-trie/std", "thiserror"] # Enables the `to_json` function for `Pair` and `Pairs`