diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/emitter.rs | 19 | ||||
| -rw-r--r-- | src/spans.rs | 57 | ||||
| -rw-r--r-- | src/tokenizer.rs | 1 | 
3 files changed, 48 insertions, 29 deletions
| diff --git a/src/emitter.rs b/src/emitter.rs index e441eb7..18b2539 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -5,6 +5,7 @@ use std::collections::VecDeque;  use std::marker::PhantomData;  use std::mem; +use crate::spans::Position;  use crate::spans::Span;  use crate::Error; @@ -183,7 +184,7 @@ impl<R, S> Default for DefaultEmitter<R, S> {      }  } -impl<R, S: Span<R>> DefaultEmitter<R, S> { +impl<R, S: Span> DefaultEmitter<R, S> {      fn emit_token(&mut self, token: Token<S>) {          self.flush_current_characters();          self.emitted_tokens.push_front(token); @@ -229,7 +230,7 @@ impl<R, S: Span<R>> DefaultEmitter<R, S> {      }  } -impl<R, S: Span<R>> Emitter<R> for DefaultEmitter<R, S> { +impl<R: Position<S::Offset>, S: Span> Emitter<R> for DefaultEmitter<R, S> {      type Token = Token<S>;      fn emit_eof(&mut self) { @@ -237,7 +238,7 @@ impl<R, S: Span<R>> Emitter<R> for DefaultEmitter<R, S> {      }      fn emit_error(&mut self, error: Error, reader: &R) { -        self.push_error(error, S::from_reader(reader)); +        self.push_error(error, S::new(reader.position(), reader.position()));      }      fn pop_token(&mut self) -> Option<Self::Token> { @@ -250,7 +251,7 @@ impl<R, S: Span<R>> Emitter<R> for DefaultEmitter<R, S> {      fn init_start_tag(&mut self, reader: &R) {          self.current_token = Some(Token::StartTag(StartTag { -            name_span: S::from_reader(reader), +            name_span: S::new(reader.position(), reader.position()),              self_closing: false,              name: String::new(),              attributes: Default::default(), @@ -258,7 +259,7 @@ impl<R, S: Span<R>> Emitter<R> for DefaultEmitter<R, S> {      }      fn init_end_tag(&mut self, reader: &R) {          self.current_token = Some(Token::EndTag(EndTag { -            name_span: S::from_reader(reader), +            name_span: S::new(reader.position(), reader.position()),              name: String::new(),          }));          self.seen_attributes.clear(); @@ -367,15 +368,17 @@ impl<R, S: Span<R>> Emitter<R> for DefaultEmitter<R, S> {          self.current_attribute = Some((              String::new(),              Attribute { -                name_span: S::from_reader(reader), +                name_span: S::new(reader.position(), reader.position()),                  value: String::new(),                  value_span: S::default(),              },          ));      }      fn init_attribute_value(&mut self, reader: &R, quoted: bool) { -        self.current_attribute.as_mut().unwrap().1.value_span = -            S::from_reader_with_offset(reader, quoted as usize); +        self.current_attribute.as_mut().unwrap().1.value_span = S::new( +            reader.position() + quoted as usize, +            reader.position() + quoted as usize, +        );      }      fn push_attribute_name(&mut self, s: &str) { diff --git a/src/spans.rs b/src/spans.rs index 89595aa..14392cd 100644 --- a/src/spans.rs +++ b/src/spans.rs @@ -6,21 +6,29 @@  //! * one for `()` which acts as the no-op implementation for when you don't want to track spans  //! * one for [`Range<usize>`] for when you do want to track spans  //! -//! To use the latter your reader however has to implement [`Position`]. +//! To use the latter your reader however has to implement [`Position<usize>`].  //! You can easily use any existing reader by wrapping it in the [`PosTrackingReader`] struct -//! which implements the [`Position`] trait and takes care of tracking the current position. +//! which implements the [`Position<usize>`] trait and takes care of tracking the current position. -use std::ops::Range; +use std::ops::{Add, Range};  use crate::reader::{IntoReader, Reader}; +pub struct NoopOffset; +  /// A trait to be implemented by readers that track their own position. -pub trait Position { +pub trait Position<T> {      /// Returns the byte index of the current position. -    fn position(&self) -> usize; +    fn position(&self) -> T; +} + +impl<R: Reader> Position<NoopOffset> for R { +    fn position(&self) -> NoopOffset { +        NoopOffset +    }  } -/// Wraps a [`Reader`] so that it implements [`Position`]. +/// Wraps a [`Reader`] so that it implements [`Position<usize>`].  pub struct PosTrackingReader<R> {      /// The wrapped reader.      reader: R, @@ -29,7 +37,7 @@ pub struct PosTrackingReader<R> {  }  impl<R> PosTrackingReader<R> { -    /// Wraps the given [`Reader`] so that it implements [`Position`] with the position starting from 0. +    /// Wraps the given [`Reader`] so that it implements [`Position<usize>`] with the position starting from 0.      pub fn new<'a>(into_reader: impl IntoReader<'a, Reader = R>) -> Self {          Self {              reader: into_reader.into_reader(), @@ -38,39 +46,46 @@ impl<R> PosTrackingReader<R> {      }  } -impl<R> Position for PosTrackingReader<R> { +impl<R> Position<usize> for PosTrackingReader<R> {      fn position(&self) -> usize {          self.position      }  }  /// A byte range in the source code. -pub trait Span<R>: Default + Clone { -    /// Initializes a new span at the current position of the reader. -    fn from_reader(reader: &R) -> Self; +pub trait Span: Default + Clone { +    type Offset: Add<usize, Output = Self::Offset>; -    /// Initializes a new span at the current position of the reader with the given offset. -    fn from_reader_with_offset(reader: &R, offset: usize) -> Self; +    /// Constructs a new span from the given byte offsets. +    fn new(start: Self::Offset, end: Self::Offset) -> Self;      /// Extends the span by the length of the given string.      fn push_str(&mut self, str: &str);  } -impl<R> Span<R> for () { -    fn from_reader(_reader: &R) -> Self {} +impl Span for () { +    type Offset = NoopOffset; -    fn from_reader_with_offset(_reader: &R, _offset: usize) -> Self {} +    fn new(_start: Self::Offset, _end: Self::Offset) -> Self { +        () +    }      fn push_str(&mut self, _str: &str) {}  } -impl<P: Position> Span<P> for Range<usize> { -    fn from_reader(reader: &P) -> Self { -        reader.position() - 1..reader.position() - 1 +impl Add<usize> for NoopOffset { +    type Output = Self; + +    fn add(self, _rhs: usize) -> NoopOffset { +        self      } +} + +impl Span for Range<usize> { +    type Offset = usize; -    fn from_reader_with_offset(reader: &P, offset: usize) -> Self { -        reader.position() - 1 + offset..reader.position() - 1 + offset +    fn new(start: Self::Offset, end: Self::Offset) -> Self { +        start - 1..end - 1      }      fn push_str(&mut self, str: &str) { diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 7768ee4..7b8b1ce 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -1,5 +1,6 @@  use crate::machine;  use crate::reader::{IntoReader, Reader}; +use crate::spans::Position;  use crate::utils::{      control_pat, noncharacter_pat, surrogate_pat, ControlToken, State as InternalState,  }; | 
