@@ -41,6 +41,57 @@ pub struct Line {
41
41
pub annotations : Vec < Annotation > ,
42
42
}
43
43
44
+ #[ derive( Clone , Debug , PartialOrd , Ord , PartialEq , Eq ) ]
45
+ pub enum AnnotationType {
46
+ /// Annotation under a single line of code
47
+ Singleline ,
48
+
49
+ /// Annotation under the first character of a multiline span
50
+ Minimized ,
51
+
52
+ /// Annotation enclosing the first and last character of a multiline span
53
+ Multiline {
54
+ depth : usize ,
55
+ line_start : usize ,
56
+ line_end : usize ,
57
+ } ,
58
+
59
+ // The Multiline type above is replaced with the following three in order
60
+ // to reuse the current label drawing code.
61
+ //
62
+ // Each of these corresponds to one part of the following diagram:
63
+ //
64
+ // x | foo(1 + bar(x,
65
+ // | _________^ starting here... < MultilineStart
66
+ // x | | y), < MultilineLine
67
+ // | |______________^ ...ending here: label < MultilineEnd
68
+ // x | z);
69
+ /// Annotation marking the first character of a fully shown multiline span
70
+ MultilineStart ( usize ) ,
71
+ /// Annotation marking the last character of a fully shown multiline span
72
+ MultilineEnd ( usize ) ,
73
+ /// Line at the left enclosing the lines of a fully shown multiline span
74
+ MultilineLine ( usize ) ,
75
+ }
76
+
77
+ impl AnnotationType {
78
+ pub fn depth ( & self ) -> usize {
79
+ match self {
80
+ & AnnotationType :: Multiline { depth, ..} |
81
+ & AnnotationType :: MultilineStart ( depth) |
82
+ & AnnotationType :: MultilineLine ( depth) |
83
+ & AnnotationType :: MultilineEnd ( depth) => depth,
84
+ _ => 0 ,
85
+ }
86
+ }
87
+
88
+ pub fn increase_depth ( & mut self ) {
89
+ if let AnnotationType :: Multiline { ref mut depth, ..} = * self {
90
+ * depth += 1 ;
91
+ }
92
+ }
93
+ }
94
+
44
95
#[ derive( Clone , Debug , PartialOrd , Ord , PartialEq , Eq ) ]
45
96
pub struct Annotation {
46
97
/// Start column, 0-based indexing -- counting *characters*, not
@@ -55,11 +106,57 @@ pub struct Annotation {
55
106
/// Is this annotation derived from primary span
56
107
pub is_primary : bool ,
57
108
58
- /// Is this a large span minimized down to a smaller span
59
- pub is_minimized : bool ,
60
-
61
109
/// Optional label to display adjacent to the annotation.
62
110
pub label : Option < String > ,
111
+
112
+ /// Is this a single line, multiline or multiline span minimized down to a
113
+ /// smaller span.
114
+ pub annotation_type : AnnotationType ,
115
+ }
116
+
117
+ impl Annotation {
118
+ pub fn is_minimized ( & self ) -> bool {
119
+ match self . annotation_type {
120
+ AnnotationType :: Minimized => true ,
121
+ _ => false ,
122
+ }
123
+ }
124
+
125
+ pub fn is_multiline ( & self ) -> bool {
126
+ match self . annotation_type {
127
+ AnnotationType :: Multiline { ..} |
128
+ AnnotationType :: MultilineStart ( _) |
129
+ AnnotationType :: MultilineLine ( _) |
130
+ AnnotationType :: MultilineEnd ( _) => true ,
131
+ _ => false ,
132
+ }
133
+ }
134
+
135
+ pub fn as_start ( & self ) -> Annotation {
136
+ let mut a = self . clone ( ) ;
137
+ a. annotation_type = AnnotationType :: MultilineStart ( self . annotation_type . depth ( ) ) ;
138
+ a. end_col = a. start_col + 1 ;
139
+ a. label = Some ( "starting here..." . to_owned ( ) ) ;
140
+ a
141
+ }
142
+
143
+ pub fn as_end ( & self ) -> Annotation {
144
+ let mut a = self . clone ( ) ;
145
+ a. annotation_type = AnnotationType :: MultilineEnd ( self . annotation_type . depth ( ) ) ;
146
+ a. start_col = a. end_col - 1 ;
147
+ a. label = match a. label {
148
+ Some ( l) => Some ( format ! ( "...ending here: {}" , l) ) ,
149
+ None => Some ( "..ending here" . to_owned ( ) ) ,
150
+ } ;
151
+ a
152
+ }
153
+
154
+ pub fn as_line ( & self ) -> Annotation {
155
+ let mut a = self . clone ( ) ;
156
+ a. annotation_type = AnnotationType :: MultilineLine ( self . annotation_type . depth ( ) ) ;
157
+ a. label = None ;
158
+ a
159
+ }
63
160
}
64
161
65
162
#[ derive( Debug ) ]
0 commit comments