]> git.lizzy.rs Git - rust.git/blob - src/text.rs
Add minimal docs to most public symbols
[rust.git] / src / text.rs
1 use std::fmt;
2 use std::ops;
3
4 /// An text position in a source file
5 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6 pub struct TextUnit(u32);
7
8 impl TextUnit {
9     /// The positional offset required for one character
10     pub fn len_of_char(c: char) -> TextUnit {
11         TextUnit(c.len_utf8() as u32)
12     }
13
14     #[allow(missing_docs)]
15     pub fn new(val: u32) -> TextUnit {
16         TextUnit(val)
17     }
18 }
19
20 impl fmt::Debug for TextUnit {
21     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22         <Self as fmt::Display>::fmt(self, f)
23     }
24 }
25
26 impl fmt::Display for TextUnit {
27     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28         self.0.fmt(f)
29     }
30 }
31
32 impl From<TextUnit> for u32 {
33     fn from(tu: TextUnit) -> u32 {
34         tu.0
35     }
36 }
37
38 impl From<u32> for TextUnit {
39     fn from(tu: u32) -> TextUnit {
40         TextUnit::new(tu)
41     }
42 }
43
44 impl ops::Add<TextUnit> for TextUnit {
45     type Output = TextUnit;
46     fn add(self, rhs: TextUnit) -> TextUnit {
47         TextUnit(self.0 + rhs.0)
48     }
49 }
50
51 impl ops::AddAssign<TextUnit> for TextUnit {
52     fn add_assign(&mut self, rhs: TextUnit) {
53         self.0 += rhs.0
54     }
55 }
56
57 impl ops::Sub<TextUnit> for TextUnit {
58     type Output = TextUnit;
59     fn sub(self, rhs: TextUnit) -> TextUnit {
60         TextUnit(self.0 - rhs.0)
61     }
62 }
63
64 impl ops::SubAssign<TextUnit> for TextUnit {
65     fn sub_assign(&mut self, rhs: TextUnit) {
66         self.0 -= rhs.0
67     }
68 }
69
70 /// A range of text in a source file
71 #[derive(Clone, Copy, PartialEq, Eq)]
72 pub struct TextRange {
73     start: TextUnit,
74     end: TextUnit,
75 }
76
77 impl fmt::Debug for TextRange {
78     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79         <Self as fmt::Display>::fmt(self, f)
80     }
81 }
82
83 impl fmt::Display for TextRange {
84     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85         write!(f, "[{}; {})", self.start(), self.end())
86     }
87 }
88
89 impl TextRange {
90     /// An length-0 range of text
91     pub fn empty() -> TextRange {
92         TextRange::from_to(TextUnit::new(0), TextUnit::new(0))
93     }
94
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);
98         TextRange {
99             start: from,
100             end: to,
101         }
102     }
103
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)
107     }
108
109     /// The starting position of this range
110     pub fn start(&self) -> TextUnit {
111         self.start
112     }
113
114     /// The end position of this range
115     pub fn end(&self) -> TextUnit {
116         self.end
117     }
118
119     /// The length of this range
120     pub fn len(&self) -> TextUnit {
121         self.end - self.start
122     }
123
124     /// Is this range empty of any content?
125     pub fn is_empty(&self) -> bool {
126         self.start() == self.end()
127     }
128 }
129
130 impl ops::Index<TextRange> for str {
131     type Output = str;
132
133     fn index(&self, index: TextRange) -> &str {
134         &self[index.start().0 as usize..index.end().0 as usize]
135     }
136 }