From 8a525f753b801f551e8012340e106c7084570806 Mon Sep 17 00:00:00 2001 From: Noah Hellman Date: Tue, 6 Dec 2022 21:55:46 +0100 Subject: [PATCH] wip --- src/block.rs | 9 +++------ src/span.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/block.rs b/src/block.rs index a0f20fd..3d3272d 100644 --- a/src/block.rs +++ b/src/block.rs @@ -95,10 +95,7 @@ impl<'s> Parser<'s> { let first = &mut lines[0]; *first = first.with_start(span.end()); // trim starting whitespace of block - *first = Span::new( - first.end() - first.of(self.src).trim_start().len(), - first.end(), - ); + *first = first.trim_start(self.src); let line_count = match l { CodeBlock { .. } => line_count - 1, _ => line_count, @@ -106,7 +103,7 @@ impl<'s> Parser<'s> { if !matches!(l, Leaf::CodeBlock { .. }) { // trim ending whitespace of block let last = &mut lines[line_count - 1]; - *last = last.with_len(last.of(self.src).trim_end().len()); + *last = last.trim_end(self.src); } for line in &lines[0..line_count] { self.tree.elem(Atom::Inline, *line); @@ -134,7 +131,7 @@ impl<'s> Parser<'s> { .count() + usize::from(skip_chars)) .min(sp.len()); - *sp = sp.trim_start(skip); + *sp = sp.skip(skip); }); self.tree.enter(kind, span); diff --git a/src/span.rs b/src/span.rs index e81a364..6d2f49a 100644 --- a/src/span.rs +++ b/src/span.rs @@ -28,8 +28,8 @@ impl Span { Self::by_len(self.start(), len) } - pub fn trim_start(self, n: usize) -> Self { - Self::new(self.start().checked_add(n).unwrap(), self.end()) + pub fn skip(self, n: usize) -> Self { + Self::new(self.start() + n, self.end()) } pub fn translate(self, n: usize) -> Self { @@ -66,4 +66,48 @@ impl Span { pub fn of(self, s: &str) -> &str { &s[self.start()..self.end()] } + + pub fn from_slice(s: &str, slice: &str) -> Self { + Self::by_len(slice.as_ptr() as usize - s.as_ptr() as usize, slice.len()) + } + + pub fn trim_start(self, s: &str) -> Self { + Self::from_slice(s, self.of(s).trim_start()) + } + + pub fn trim_end(self, s: &str) -> Self { + Self::from_slice(s, self.of(s).trim_end()) + } + + pub fn trim(self, s: &str) -> Self { + Self::from_slice(s, self.of(s).trim_start().trim_end()) + } +} + +#[cfg(test)] +mod test { + use super::Span; + + #[test] + fn from_slice() { + let src = "0123456789"; + assert_eq!(Span::from_slice(src, &src[0..0]), Span::new(0, 0)); + assert_eq!(Span::from_slice(src, &src[0..5]), Span::new(0, 5)); + assert_eq!(Span::from_slice(src, &src[5..5]), Span::new(5, 5)); + assert_eq!(Span::from_slice(src, &src[5..8]), Span::new(5, 8)); + assert_eq!(Span::from_slice(src, &src[5..10]), Span::new(5, 10)); + assert_eq!(Span::from_slice(src, &src[5..]), Span::new(5, 10)); + } + + #[test] + fn trim() { + let src = " 23456 "; + assert_eq!(Span::by_len(0, src.len()).trim_start(src), Span::new(2, 10)); + assert_eq!(Span::by_len(0, src.len()).trim_end(src), Span::new(0, 7)); + assert_eq!(Span::by_len(0, src.len()).trim(src), Span::new(2, 7)); + assert_eq!( + Span::by_len(0, src.len()).trim_start(src).trim_end(src), + Span::new(2, 7) + ); + } }