tamer: span::Span::endpoints_saturated: New method
This gets rid of the `Option` and is used in the diagnostic system (next commit). DEV-10935main
parent
a22e8e79f7
commit
e555955450
|
@ -220,6 +220,10 @@ pub struct Span {
|
||||||
|
|
||||||
/// Context onto which byte offsets are mapped,
|
/// Context onto which byte offsets are mapped,
|
||||||
/// such as a source file.
|
/// such as a source file.
|
||||||
|
///
|
||||||
|
/// N.B.: This is an unaligned field,
|
||||||
|
/// and accessing it frequently may have a negative impact on
|
||||||
|
/// performance.
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +374,49 @@ impl Span {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create two zero-length spans representing respectively the first and
|
||||||
|
/// last offsets in the span,
|
||||||
|
/// saturating the ending offset if it cannot be represented by
|
||||||
|
/// [`SpanOffsetSize`].
|
||||||
|
///
|
||||||
|
/// Aside from the saturation,
|
||||||
|
/// this is identical to [`Span::endpoints`].
|
||||||
|
pub fn endpoints_saturated(self) -> (Self, Self) {
|
||||||
|
let endpoints = self.endpoints();
|
||||||
|
|
||||||
|
(
|
||||||
|
endpoints.0,
|
||||||
|
endpoints.1.unwrap_or(Self {
|
||||||
|
offset: SpanOffsetSize::MAX,
|
||||||
|
..endpoints.0
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adjust span such that its offset is relative to the provided span.
|
||||||
|
///
|
||||||
|
/// If the provide `rel_span` does not precede this span,
|
||||||
|
/// [`None`] will be returned.
|
||||||
|
///
|
||||||
|
/// If the two spans do not share the same [`Context`],
|
||||||
|
/// no comparison can be made and [`None`] will be returned.
|
||||||
|
pub fn relative_to(self, rel_span: Span) -> Option<Self> {
|
||||||
|
// Note that this is unaligned.
|
||||||
|
if self.ctx() != rel_span.ctx() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.offset() < rel_span.offset() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(Self {
|
||||||
|
ctx: self.ctx,
|
||||||
|
offset: self.offset.saturating_sub(rel_span.offset),
|
||||||
|
len: self.len,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<u64> for Span {
|
impl Into<u64> for Span {
|
||||||
|
@ -676,4 +723,28 @@ mod test {
|
||||||
assert_eq!(start, Span::new(10, 0, ctx));
|
assert_eq!(start, Span::new(10, 0, ctx));
|
||||||
assert_eq!(end, Some(Span::new(30, 0, ctx)));
|
assert_eq!(end, Some(Span::new(30, 0, ctx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn span_endpoints_exceeding_max_offset() {
|
||||||
|
let ctx = Context::from("end");
|
||||||
|
let offset = SpanOffsetSize::MAX - 5;
|
||||||
|
let span = ctx.span(offset, 10);
|
||||||
|
|
||||||
|
let (start, end) = span.endpoints();
|
||||||
|
|
||||||
|
assert_eq!(start, Span::new(offset, 0, ctx));
|
||||||
|
assert_eq!(end, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn span_endpoints_saturated() {
|
||||||
|
let ctx = Context::from("end");
|
||||||
|
let offset = SpanOffsetSize::MAX - 5;
|
||||||
|
let span = ctx.span(offset, 10);
|
||||||
|
|
||||||
|
let (start, end) = span.endpoints_saturated();
|
||||||
|
|
||||||
|
assert_eq!(start, Span::new(offset, 0, ctx));
|
||||||
|
assert_eq!(end, Span::new(SpanOffsetSize::MAX, 0, ctx));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue