11use super :: annotation:: Annotation ;
2- use super :: line:: { DisplayLine , DisplayRawLine , DisplaySourceLine } ;
3- use crate :: slice:: Slice ;
2+ use super :: line:: {
3+ DisplayAnnotationType , DisplayLine , DisplayMark , DisplayMarkType , DisplayRawLine ,
4+ DisplaySourceLine ,
5+ } ;
6+ use crate :: slice:: { Slice , SourceAnnotation } ;
7+ use std:: cmp;
48use std:: fmt;
59
610#[ derive( Debug , Clone ) ]
@@ -26,46 +30,95 @@ impl<'d> From<&Slice<'d>> for DisplayList<'d> {
2630
2731 body. push ( DisplayLine :: Source {
2832lineno : None ,
33+ inline_marks : vec ! [ ] ,
2934line : DisplaySourceLine :: Empty ,
3035} ) ;
3136
32- let mut annotations = slice. annotations . iter ( ) ;
37+ let mut annotations: Vec < & SourceAnnotation > = slice. annotations . iter ( ) . collect ( ) ;
3338
34- let mut current_annotation = annotations. next ( ) ;
39+ // let mut current_annotation = annotations.next();
3540let mut line_start_pos =0 ;
3641
3742let mut i = slice. line_start . unwrap_or ( 1 ) ;
3843for linein slice. source . lines ( ) {
3944let line_length = line. chars ( ) . count ( ) ;
45+
46+ let mut current_annotations =vec ! [ ] ;
47+ let mut inline_marks =vec ! [ ] ;
48+
49+ annotations. retain ( |ann|{
50+ if ann. range . 0 >= line_start_pos && ann. range . 1 <= line_start_pos + line_length{
51+ // Annotation in this line
52+ current_annotations. push ( * ann) ;
53+ false
54+ } else if ann. range . 0 >= line_start_pos
55+ && ann. range . 0 <= line_start_pos + line_length
56+ {
57+ // Annotation starts in this line
58+ inline_marks. push ( DisplayMark {
59+ mark_type : DisplayMarkType :: AnnotationStart ,
60+ annotation_type : DisplayAnnotationType :: Error ,
61+ } ) ;
62+ true
63+ } else if ann. range . 0 < line_start_pos && ann. range . 1 > line_start_pos + line_length
64+ {
65+ // Annotation goes through this line
66+ inline_marks. push ( DisplayMark {
67+ mark_type : DisplayMarkType :: AnnotationThrough ,
68+ annotation_type : DisplayAnnotationType :: Error ,
69+ } ) ;
70+ true
71+ } else if ann. range . 0 < line_start_pos
72+ && ann. range . 1 >= line_start_pos
73+ && ann. range . 1 <= line_start_pos + line_length
74+ {
75+ // Annotation ends on this line
76+ inline_marks. push ( DisplayMark {
77+ mark_type : DisplayMarkType :: AnnotationThrough ,
78+ annotation_type : DisplayAnnotationType :: Error ,
79+ } ) ;
80+ current_annotations. push ( * ann) ;
81+ false
82+ } else {
83+ true
84+ }
85+ } ) ;
86+
4087 body. push ( DisplayLine :: Source {
4188lineno : Some ( i) ,
89+ inline_marks,
4290line : DisplaySourceLine :: Content { text : line} ,
4391} ) ;
44- if let Some ( annotation) = current_annotation{
45- if annotation. range . 0 >= line_start_pos
46- && annotation. range . 1 <= line_start_pos + line_length
47- {
48- body. push ( DisplayLine :: Source {
49- lineno : None ,
50- line : DisplaySourceLine :: Annotation {
51- annotation : Annotation {
52- label : annotation. label ,
53- } ,
54- range : (
55- annotation. range . 0 - line_start_pos,
56- annotation. range . 1 - line_start_pos,
57- ) ,
58- } ,
59- } ) ;
60- current_annotation = annotations. next ( ) ;
61- }
92+ for annin current_annotations{
93+ let start =if ann. range . 0 >= line_start_pos{
94+ ann. range . 0 - line_start_pos
95+ } else {
96+ 0
97+ } ;
98+ let inline_marks =if ann. range . 0 < line_start_pos{
99+ vec ! [ DisplayMark {
100+ mark_type: DisplayMarkType :: AnnotationThrough ,
101+ annotation_type: DisplayAnnotationType :: Error ,
102+ } ]
103+ } else {
104+ vec ! [ ]
105+ } ;
106+ body. push ( DisplayLine :: Source {
107+ lineno : None ,
108+ inline_marks,
109+ line : DisplaySourceLine :: Annotation {
110+ annotation : Annotation { label : ann. label } ,
111+ range : ( start, ann. range . 1 - line_start_pos) ,
112+ } ,
113+ } ) ;
62114}
63115 line_start_pos += line_length;
64116 i +=1 ;
65117}
66118
67119 body. push ( DisplayLine :: Source {
68120lineno : None ,
121+ inline_marks : vec ! [ ] ,
69122line : DisplaySourceLine :: Empty ,
70123} ) ;
71124
@@ -96,8 +149,12 @@ impl<'d> fmt::Display for DisplayList<'d> {
96149None
97150}
98151} ) ;
152+ let inline_marks_width =self . body . iter ( ) . fold ( 0 , |max, line|match line{
153+ DisplayLine :: Source { inline_marks, ..} => cmp:: max ( inline_marks. len ( ) , max) ,
154+ _ => max,
155+ } ) ;
99156for linein & self . body {
100- line. fmt ( f, lineno_max) ?
157+ line. fmt ( f, lineno_max, inline_marks_width ) ?
101158}
102159Ok ( ( ) )
103160}