annotate_snippets/renderer/
margin.rs1use core::cmp::{max, min};
2
3const ELLIPSIS_PASSING: usize = 6;
4const LONG_WHITESPACE: usize = 20;
5const LONG_WHITESPACE_PADDING: usize = 4;
6
7#[derive(Clone, Copy, Debug, PartialEq)]
8pub(crate) struct Margin {
9 whitespace_left: usize,
11 span_left: usize,
13 span_right: usize,
15 computed_left: usize,
17 computed_right: usize,
19 pub(crate) term_width: usize,
21 label_right: usize,
24}
25
26impl Margin {
27 pub(crate) fn new(
28 whitespace_left: usize,
29 span_left: usize,
30 span_right: usize,
31 label_right: usize,
32 term_width: usize,
33 max_line_len: usize,
34 ) -> Self {
35 let whitespace_left = min(whitespace_left, span_left);
44
45 let mut m = Self {
55 whitespace_left: whitespace_left.saturating_sub(ELLIPSIS_PASSING),
56 span_left: span_left.saturating_sub(ELLIPSIS_PASSING),
57 span_right: span_right + ELLIPSIS_PASSING,
58 computed_left: 0,
59 computed_right: 0,
60 term_width,
61 label_right: label_right + ELLIPSIS_PASSING,
62 };
63 m.compute(max_line_len);
64 m
65 }
66
67 pub(crate) fn was_cut_left(&self) -> bool {
68 self.computed_left > 0
69 }
70
71 fn compute(&mut self, max_line_len: usize) {
72 self.computed_left = if self.whitespace_left > LONG_WHITESPACE {
74 self.whitespace_left - (LONG_WHITESPACE - LONG_WHITESPACE_PADDING) } else {
76 0
77 };
78 self.computed_right = max(max_line_len, self.computed_left);
81
82 if self.computed_right - self.computed_left > self.term_width {
83 if self.label_right.saturating_sub(self.whitespace_left) <= self.term_width
85 && self.label_right >= self.whitespace_left
89 {
90 self.computed_left = self.whitespace_left;
92 self.computed_right = self.computed_left + self.term_width;
93 } else if self.label_right - self.span_left <= self.term_width {
94 let padding_left = (self.term_width - (self.label_right - self.span_left)) / 2;
96 self.computed_left = self.span_left.saturating_sub(padding_left);
97 self.computed_right = self.computed_left + self.term_width;
98 } else if self.span_right - self.span_left <= self.term_width {
99 let padding_left = (self.term_width - (self.span_right - self.span_left)) / 5 * 2;
101 self.computed_left = self.span_left.saturating_sub(padding_left);
102 self.computed_right = self.computed_left + self.term_width;
103 } else {
104 self.computed_left = self.span_left;
106 self.computed_right = self.span_right;
107 }
108 }
109 }
110
111 pub(crate) fn left(&self, line_len: usize) -> usize {
112 min(self.computed_left, line_len)
113 }
114
115 pub(crate) fn right(&self, line_len: usize) -> usize {
116 if line_len.saturating_sub(self.computed_left) <= self.term_width {
117 line_len
118 } else {
119 min(line_len, self.computed_right)
120 }
121 }
122}