4 /// An text position in a source file
5 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6 pub struct TextUnit(u32);
9 /// The positional offset required for one character
10 pub fn len_of_char(c: char) -> TextUnit {
11 TextUnit(c.len_utf8() as u32)
14 #[allow(missing_docs)]
15 pub fn new(val: u32) -> TextUnit {
20 impl fmt::Debug for TextUnit {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 <Self as fmt::Display>::fmt(self, f)
26 impl fmt::Display for TextUnit {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 impl From<TextUnit> for u32 {
33 fn from(tu: TextUnit) -> u32 {
38 impl From<u32> for TextUnit {
39 fn from(tu: u32) -> TextUnit {
44 impl ops::Add<TextUnit> for TextUnit {
45 type Output = TextUnit;
46 fn add(self, rhs: TextUnit) -> TextUnit {
47 TextUnit(self.0 + rhs.0)
51 impl ops::AddAssign<TextUnit> for TextUnit {
52 fn add_assign(&mut self, rhs: TextUnit) {
57 impl ops::Sub<TextUnit> for TextUnit {
58 type Output = TextUnit;
59 fn sub(self, rhs: TextUnit) -> TextUnit {
60 TextUnit(self.0 - rhs.0)
64 impl ops::SubAssign<TextUnit> for TextUnit {
65 fn sub_assign(&mut self, rhs: TextUnit) {
70 /// A range of text in a source file
71 #[derive(Clone, Copy, PartialEq, Eq)]
72 pub struct TextRange {
77 impl fmt::Debug for TextRange {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 <Self as fmt::Display>::fmt(self, f)
83 impl fmt::Display for TextRange {
84 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85 write!(f, "[{}; {})", self.start(), self.end())
90 /// An length-0 range of text
91 pub fn empty() -> TextRange {
92 TextRange::from_to(TextUnit::new(0), TextUnit::new(0))
95 /// The left-inclusive range (`[from..to)`) between to points in the text
96 pub fn from_to(from: TextUnit, to: TextUnit) -> TextRange {
97 assert!(from <= to, "Invalid text range [{}; {})", from, to);
104 /// The range from some point over some length
105 pub fn from_len(from: TextUnit, len: TextUnit) -> TextRange {
106 TextRange::from_to(from, from + len)
109 /// The starting position of this range
110 pub fn start(&self) -> TextUnit {
114 /// The end position of this range
115 pub fn end(&self) -> TextUnit {
119 /// The length of this range
120 pub fn len(&self) -> TextUnit {
121 self.end - self.start
124 /// Is this range empty of any content?
125 pub fn is_empty(&self) -> bool {
126 self.start() == self.end()
130 impl ops::Index<TextRange> for str {
133 fn index(&self, index: TextRange) -> &str {
134 &self[index.start().0 as usize..index.end().0 as usize]