pub struct Span { /* private fields */ }Expand description
A half-open byte range start..end into a single source.
A Span is two packed BytePos offsets — eight bytes, Copy — that a
lexer attaches to every token and a parser threads through every node. The
range is half-open: start is included, end is not, so the length is
exactly end - start and adjacent spans (a.end == b.start) do not overlap.
§Invariant
start <= end always holds. Span::new enforces it by ordering its two
arguments, so a span can never be constructed inverted, and every method may
rely on it. An empty span (start == end) is legal and marks a zero-width
point — the position of an insertion, or a token with no text.
Spans order lexicographically by start then end, so a slice of spans sorts
into source order.
§Examples
use span_lang::Span;
let s = Span::new(4, 10);
assert_eq!(s.len(), 6);
assert!(!s.is_empty());
// Arguments are ordered, so an inverted call still yields a valid span.
assert_eq!(Span::new(10, 4), Span::new(4, 10));Implementations§
Source§impl Span
impl Span
Sourcepub const fn new(start: u32, end: u32) -> Span
pub const fn new(start: u32, end: u32) -> Span
Constructs a span covering start..end.
If start > end the two are swapped, so the result always upholds the
start <= end invariant. This makes construction total — it never panics,
whatever offsets a caller supplies — which matters when the offsets come
from arithmetic on untrusted input.
§Examples
use span_lang::Span;
let s = Span::new(2, 7);
assert_eq!(s.start().to_u32(), 2);
assert_eq!(s.end().to_u32(), 7);
// Ordering is normalised.
assert_eq!(Span::new(7, 2), s);Sourcepub const fn empty(at: u32) -> Span
pub const fn empty(at: u32) -> Span
Constructs an empty, zero-width span at at.
Equivalent to Span::new(at, at). Use it to mark a point — for instance,
the caret position for an “expected token here” diagnostic.
§Examples
use span_lang::Span;
let point = Span::empty(5);
assert!(point.is_empty());
assert_eq!(point.len(), 0);Sourcepub const fn start(self) -> BytePos
pub const fn start(self) -> BytePos
Returns the start position (inclusive).
§Examples
use span_lang::{BytePos, Span};
assert_eq!(Span::new(3, 8).start(), BytePos::new(3));Sourcepub const fn end(self) -> BytePos
pub const fn end(self) -> BytePos
Returns the end position (exclusive).
§Examples
use span_lang::{BytePos, Span};
assert_eq!(Span::new(3, 8).end(), BytePos::new(8));Sourcepub const fn len(self) -> u32
pub const fn len(self) -> u32
Returns the length of the span in bytes.
Always end - start, which the invariant guarantees is non-negative.
§Examples
use span_lang::Span;
assert_eq!(Span::new(4, 10).len(), 6);
assert_eq!(Span::empty(4).len(), 0);Sourcepub const fn is_empty(self) -> bool
pub const fn is_empty(self) -> bool
Returns true if the span is zero-width (start == end).
§Examples
use span_lang::Span;
assert!(Span::empty(9).is_empty());
assert!(!Span::new(9, 12).is_empty());Sourcepub const fn contains(self, pos: BytePos) -> bool
pub const fn contains(self, pos: BytePos) -> bool
Returns true if pos falls within the span (start <= pos < end).
Membership is half-open to match the range: the end position is not
contained, and an empty span contains no position at all.
§Examples
use span_lang::{BytePos, Span};
let s = Span::new(4, 8);
assert!(s.contains(BytePos::new(4))); // start is included
assert!(s.contains(BytePos::new(7)));
assert!(!s.contains(BytePos::new(8))); // end is excluded
assert!(!Span::empty(4).contains(BytePos::new(4)));Sourcepub const fn merge(self, other: Span) -> Span
pub const fn merge(self, other: Span) -> Span
Returns the smallest span that covers both self and other.
The result spans min(starts)..max(ends). merge is commutative
(a.merge(b) == b.merge(a)) and associative
(a.merge(b).merge(c) == a.merge(b.merge(c))), so the order spans are
combined in never changes the result — useful when folding a node’s span
over its children.
§Examples
use span_lang::Span;
let a = Span::new(4, 10);
let b = Span::new(8, 14);
assert_eq!(a.merge(b), Span::new(4, 14));
// Disjoint spans merge to the range that encloses both.
assert_eq!(Span::new(0, 2).merge(Span::new(20, 24)), Span::new(0, 24));Trait Implementations§
impl Copy for Span
Source§impl<'de> Deserialize<'de> for Span
Available on crate feature serde only.
impl<'de> Deserialize<'de> for Span
serde only.Source§fn deserialize<D>(
deserializer: D,
) -> Result<Span, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn deserialize<D>(
deserializer: D,
) -> Result<Span, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
Deserialises { start, end } and routes it through Span::new, so a
span read from an untrusted source upholds the start <= end invariant
exactly as a constructed one does — an inverted pair on the wire is
normalised, never accepted as-is.
impl Eq for Span
Source§impl Ord for Span
impl Ord for Span
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for Span
impl PartialOrd for Span
Source§impl Serialize for Span
Available on crate feature serde only.
impl Serialize for Span
serde only.