check_updates_core/
output.rs1use crate::types::{DependencyCheck, UpdateSeverity};
2use colored::Colorize;
3
4pub struct TableRenderer {
6 show_colors: bool,
7}
8
9impl TableRenderer {
10 pub fn new(show_colors: bool) -> Self {
11 Self { show_colors }
12 }
13
14 pub fn render(&self, checks: &[DependencyCheck]) {
16 let checks_with_updates: Vec<&DependencyCheck> = checks
17 .iter()
18 .filter(|check| check.has_update())
19 .collect();
20
21 self.render_deduped(&checks_with_updates);
22 }
23
24 pub fn render_deduped(&self, checks: &[&DependencyCheck]) {
26 if checks.is_empty() {
27 println!("All dependencies are up to date!");
28 return;
29 }
30
31 let max_name = checks
33 .iter()
34 .map(|c| c.dependency.name.len())
35 .max()
36 .unwrap_or(0);
37
38 let max_from = checks
39 .iter()
40 .filter_map(|c| c.current_version())
41 .map(|v| v.to_string().len())
42 .max()
43 .unwrap_or(0);
44
45 let max_to = checks
46 .iter()
47 .filter_map(|c| c.target.as_ref())
48 .map(|v| v.to_string().len())
49 .max()
50 .unwrap_or(0);
51
52 println!("Outdated dependencies:\n");
53
54 for check in checks {
55 self.print_row(check, max_name, max_from, max_to);
56 }
57 }
58
59 fn print_row(
60 &self,
61 check: &DependencyCheck,
62 name_width: usize,
63 from_width: usize,
64 to_width: usize,
65 ) {
66 let from = check
67 .current_version()
68 .map(std::string::ToString::to_string)
69 .unwrap_or_default();
70
71 let to = check
72 .target
73 .as_ref()
74 .map(std::string::ToString::to_string)
75 .unwrap_or_default();
76
77 let severity_str = self.format_severity(check.severity);
78
79 let available_hint = if check.has_newer_available() {
80 format!(" ({} available)", check.latest)
81 } else {
82 String::new()
83 };
84
85 println!(
86 " {:<name_w$} {:>from_w$} → {:<to_w$} {}{}",
87 check.dependency.name,
88 from,
89 to,
90 severity_str,
91 available_hint,
92 name_w = name_width,
93 from_w = from_width,
94 to_w = to_width,
95 );
96 }
97
98 pub fn format_severity(&self, severity: Option<UpdateSeverity>) -> String {
100 match severity {
101 Some(UpdateSeverity::Major) => {
102 if self.show_colors {
103 "MAJOR".red().to_string()
104 } else {
105 "MAJOR".to_string()
106 }
107 }
108 Some(UpdateSeverity::Minor) => {
109 if self.show_colors {
110 "minor".yellow().to_string()
111 } else {
112 "minor".to_string()
113 }
114 }
115 Some(UpdateSeverity::Patch) => {
116 if self.show_colors {
117 "patch".green().to_string()
118 } else {
119 "patch".to_string()
120 }
121 }
122 None => String::new(),
123 }
124 }
125}