]> Witch of Git - ess/blob - src/span.rs
Increment version number to 0.4.1
[ess] / src / span.rs
1 //! A `Span` represents a location in source file.
2 //!
3 //! Spans are useful for reporting error messages. They're used during parsing
4 //! and are carried around in the `Sexp` type so that errors can be reported at
5 //! a higher level than the s-expressions, for example reporting semantic errors
6 //! in a Lisp implementation.
7
8 /// Represents a way of talking about a region in the source.
9 ///
10 /// All spans begin at a point in the source and contain some (possibly empty)
11 /// amount of text.
12 pub trait Span {
13 /// The `Begin` type represents the beginning point of a span.
14 type Begin;
15
16 /// Moves a `Span` forward by `begin`.
17 ///
18 /// useful for moving a relatively positioned span to start at a specific
19 /// absolute position.
20 fn offset(&self, begin: Self::Begin) -> Self;
21 /// Returns the point where a span begins.
22 fn begin(&self) -> Self::Begin;
23 /// Combines two spans into a single span that contains both of their
24 /// contents.
25 fn union(&self, other: &Self) -> Self;
26 }
27
28 /// `ByteSpan` is a very simple span, and the default for all of the parsers in
29 /// Ess.
30 ///
31 /// It represents a half-open range of bytes, the first element is the first
32 /// byte in the span and the second element is the first by after the span. This
33 /// means that `&text[span.0..span.1]` works exactly as we would expect it to.
34 pub type ByteSpan = (usize, usize);
35
36 impl Span for ByteSpan {
37 type Begin = usize;
38
39 fn offset(&self, begin: Self::Begin) -> Self {
40 (self.0 + begin, self.1 + begin)
41 }
42
43 fn begin(&self) -> Self::Begin {
44 self.0
45 }
46
47 fn union(&self, other: &Self) -> Self {
48 use std::cmp::{min, max};
49 (min(self.0, other.0), max(self.1, other.1))
50 }
51 }
52