cargo_whatfeatures/printer/
version.rs1use crate::{client::Version, Options, Theme, YankStatus};
2use std::io::Write;
3
4pub struct VersionPrinter<'a, W: ?Sized> {
6 writer: &'a mut W,
7 theme: Theme,
8 options: Options,
9}
10
11impl<'a, W: Write + ?Sized> VersionPrinter<'a, W> {
12 pub fn new(writer: &'a mut W, options: Options) -> Self {
14 Self {
15 writer,
16 theme: options.theme,
17 options,
18 }
19 }
20
21 pub fn write_versions(
23 &mut self,
24 versions: &[Version],
25 yank: YankStatus,
26 verbose: bool,
27 ) -> std::io::Result<()> {
28 use YankStatus::*;
29 let output = versions
30 .iter()
31 .filter(|ver| match (yank, ver.yanked) {
32 (Exclude, true) | (Only, false) => false,
33 _ => true,
34 })
35 .map(|version| match yank {
36 Exclude => self.write_latest(version, verbose),
37 Only => self.write_yanked(version, verbose),
38 Include if version.yanked => self.write_yanked(version, verbose),
39 Include => self.write_latest(version, verbose),
40 })
41 .collect::<Vec<_>>();
42
43 let left_max = output
44 .iter()
45 .map(|&VersionOutput { left_len, .. }| left_len)
46 .max()
47 .unwrap_or_default();
48
49 let padding = " ".repeat(left_max);
50
51 output
52 .iter()
53 .map(|v| {
54 writeln!(
55 self.writer,
56 "{}{} # {}",
57 v.left,
58 &padding[v.left_len..],
59 v.right
60 )
61 })
62 .collect()
63 }
64
65 pub fn write_many_versions(
67 &mut self,
68 list: Vec<(&String, &String, bool)>,
69 ) -> std::io::Result<()> {
70 let max = list.iter().map(|(s, ..)| s.len()).max().unwrap();
71
72 let theme = self.theme;
73 for (name, version, published) in list {
74 let header = if published {
75 format!(
76 "{: <max$} = \"{}\"",
77 theme.name.paint(&name),
78 theme.version.paint(&version),
79 max = max,
80 )
81 } else if self.options.show_private {
82 format!(
83 "{: <max$} = \"{}\" {}",
84 theme.name.paint(&name),
85 theme.version.paint(&version),
86 theme.is_not_published.paint("(restricted)"),
87 max = max,
88 )
89 } else {
90 continue;
91 };
92
93 writeln!(self.writer, "{}", header)?;
94 }
95
96 Ok(())
97 }
98
99 pub fn write_latest_version(
100 &mut self,
101 version: &Version,
102 verbose: bool,
103 ) -> std::io::Result<()> {
104 let VersionOutput { left, right, .. } = self.write_latest(version, verbose);
105 writeln!(self.writer, "{} # {}", left, right)
106 }
107
108 fn write_yanked(&mut self, version: &Version, verbose: bool) -> VersionOutput {
109 let left = format!(
110 "{} = \"{}\"",
111 self.theme.yanked.paint(&version.name),
112 self.theme.yanked.paint(&version.version),
113 );
114
115 let right = if !verbose {
116 format!(
117 "{} -- yanked",
118 self.theme
119 .created_at
120 .paint(&version.format_approx_time_span()),
121 )
122 } else {
123 format!(
124 "{} -- yanked",
125 self.theme.created_at.paint(&version.format_verbose_time()),
126 )
127 };
128
129 VersionOutput {
130 left_len: version.name.len() + version.version.len() + 3,
131 left,
132 right,
133 }
134 }
135
136 fn write_latest(&mut self, version: &Version, verbose: bool) -> VersionOutput {
137 let left = format!(
138 "{} = \"{}\"",
139 self.theme.name.paint(&version.name),
140 self.theme.version.paint(&version.version),
141 );
142
143 let right = if !verbose {
144 format!(
145 "{}",
146 self.theme
147 .created_at
148 .paint(&version.format_approx_time_span()),
149 )
150 } else {
151 format!(
152 "{}",
153 self.theme.created_at.paint(&version.format_verbose_time()),
154 )
155 };
156
157 VersionOutput {
158 left_len: version.name.len() + version.version.len() + 3,
159 left,
160 right,
161 }
162 }
163}
164
165pub struct VersionOutput {
166 left_len: usize,
167 left: String,
168 right: String,
169}