microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/merge-mines-changes

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_data_structures/src/span.rs

120lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use miette::SourceSpan;
5use std::{
6 fmt::{self, Display, Formatter},
7 ops::{Add, Index, Sub},
8};
9
10/// A region between two offsets in an array. Spans are the half-open interval `[lo, hi)`.
11#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
12pub struct Span {
13 /// The smallest offset contained in the span.
14 pub lo: u32,
15 /// The next offset after the largest offset contained in the span.
16 pub hi: u32,
17}
18
19impl Span {
20 /// Returns true if the position is within the span. Meaning it is in the
21 /// right open interval `[self.lo, self.hi)`.
22 #[must_use]
23 pub fn contains(&self, offset: u32) -> bool {
24 (self.lo..self.hi).contains(&offset)
25 }
26
27 /// Returns true if the position is in the closed interval `[self.lo, self.hi]`.
28 #[must_use]
29 pub fn touches(&self, offset: u32) -> bool {
30 (self.lo..=self.hi).contains(&offset)
31 }
32
33 /// Intersect `other` with `self` and returns a new `Span` or `None`
34 /// if the spans have no overlap.
35 #[must_use]
36 pub fn intersection(&self, other: &Self) -> Option<Self> {
37 let lo = self.lo.max(other.lo);
38 let hi = self.hi.min(other.hi);
39
40 if lo <= hi {
41 Some(Self { lo, hi })
42 } else {
43 None
44 }
45 }
46}
47
48impl Add<u32> for Span {
49 type Output = Self;
50
51 fn add(self, rhs: u32) -> Self::Output {
52 Self {
53 lo: self.lo + rhs,
54 hi: self.hi + rhs,
55 }
56 }
57}
58
59impl Sub<u32> for Span {
60 type Output = Self;
61
62 fn sub(self, rhs: u32) -> Self::Output {
63 Self {
64 lo: self.lo - rhs,
65 hi: self.hi - rhs,
66 }
67 }
68}
69
70impl Display for Span {
71 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
72 write!(f, "[{}-{}]", self.lo, self.hi)?;
73 Ok(())
74 }
75}
76
77impl Index<Span> for str {
78 type Output = str;
79
80 fn index(&self, index: Span) -> &Self::Output {
81 &self[(index.lo as usize)..(index.hi as usize)]
82 }
83}
84
85impl Index<&Span> for str {
86 type Output = str;
87
88 fn index(&self, index: &Span) -> &Self::Output {
89 &self[(index.lo as usize)..(index.hi as usize)]
90 }
91}
92
93impl Index<Span> for String {
94 type Output = str;
95
96 fn index(&self, index: Span) -> &Self::Output {
97 &self[(index.lo as usize)..(index.hi as usize)]
98 }
99}
100
101impl From<Span> for SourceSpan {
102 fn from(value: Span) -> Self {
103 Self::from((value.lo as usize)..(value.hi as usize))
104 }
105}
106
107pub trait WithSpan {
108 #[must_use]
109 fn with_span(self, span: Span) -> Self;
110}
111
112impl<T> WithSpan for Box<T>
113where
114 T: WithSpan,
115{
116 fn with_span(mut self, span: Span) -> Self {
117 *self = (*self).with_span(span);
118 self
119 }
120}
121