1 | use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq}; |
2 | use core::fmt::{self, Alignment, Debug, Display, Write}; |
3 | |
4 | impl Display for Version { |
5 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
6 | let do_display = |formatter: &mut fmt::Formatter| -> fmt::Result { |
7 | write!(formatter, " {}. {}. {}" , self.major, self.minor, self.patch)?; |
8 | if !self.pre.is_empty() { |
9 | write!(formatter, "- {}" , self.pre)?; |
10 | } |
11 | if !self.build.is_empty() { |
12 | write!(formatter, "+ {}" , self.build)?; |
13 | } |
14 | Ok(()) |
15 | }; |
16 | |
17 | let do_len = || -> usize { |
18 | digits(self.major) |
19 | + 1 |
20 | + digits(self.minor) |
21 | + 1 |
22 | + digits(self.patch) |
23 | + !self.pre.is_empty() as usize |
24 | + self.pre.len() |
25 | + !self.build.is_empty() as usize |
26 | + self.build.len() |
27 | }; |
28 | |
29 | pad(formatter, do_display, do_len) |
30 | } |
31 | } |
32 | |
33 | impl Display for VersionReq { |
34 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
35 | if self.comparators.is_empty() { |
36 | return formatter.write_str(data:"*" ); |
37 | } |
38 | for (i: usize, comparator: &Comparator) in self.comparators.iter().enumerate() { |
39 | if i > 0 { |
40 | formatter.write_str(data:", " )?; |
41 | } |
42 | write!(formatter, " {}" , comparator)?; |
43 | } |
44 | Ok(()) |
45 | } |
46 | } |
47 | |
48 | impl Display for Comparator { |
49 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
50 | let op = match self.op { |
51 | Op::Exact => "=" , |
52 | Op::Greater => ">" , |
53 | Op::GreaterEq => ">=" , |
54 | Op::Less => "<" , |
55 | Op::LessEq => "<=" , |
56 | Op::Tilde => "~" , |
57 | Op::Caret => "^" , |
58 | Op::Wildcard => "" , |
59 | #[cfg (no_non_exhaustive)] |
60 | Op::__NonExhaustive => unreachable!(), |
61 | }; |
62 | formatter.write_str(op)?; |
63 | write!(formatter, " {}" , self.major)?; |
64 | if let Some(minor) = &self.minor { |
65 | write!(formatter, ". {}" , minor)?; |
66 | if let Some(patch) = &self.patch { |
67 | write!(formatter, ". {}" , patch)?; |
68 | if !self.pre.is_empty() { |
69 | write!(formatter, "- {}" , self.pre)?; |
70 | } |
71 | } else if self.op == Op::Wildcard { |
72 | formatter.write_str(".*" )?; |
73 | } |
74 | } else if self.op == Op::Wildcard { |
75 | formatter.write_str(".*" )?; |
76 | } |
77 | Ok(()) |
78 | } |
79 | } |
80 | |
81 | impl Display for Prerelease { |
82 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
83 | formatter.write_str(self.as_str()) |
84 | } |
85 | } |
86 | |
87 | impl Display for BuildMetadata { |
88 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
89 | formatter.write_str(self.as_str()) |
90 | } |
91 | } |
92 | |
93 | impl Debug for Version { |
94 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
95 | let mut debug: DebugStruct<'_, '_> = formatter.debug_struct(name:"Version" ); |
96 | debug |
97 | .field("major" , &self.major) |
98 | .field("minor" , &self.minor) |
99 | .field(name:"patch" , &self.patch); |
100 | if !self.pre.is_empty() { |
101 | debug.field(name:"pre" , &self.pre); |
102 | } |
103 | if !self.build.is_empty() { |
104 | debug.field(name:"build" , &self.build); |
105 | } |
106 | debug.finish() |
107 | } |
108 | } |
109 | |
110 | impl Debug for Prerelease { |
111 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
112 | write!(formatter, "Prerelease( \"{}\")" , self) |
113 | } |
114 | } |
115 | |
116 | impl Debug for BuildMetadata { |
117 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
118 | write!(formatter, "BuildMetadata( \"{}\")" , self) |
119 | } |
120 | } |
121 | |
122 | fn pad( |
123 | formatter: &mut fmt::Formatter, |
124 | do_display: impl FnOnce(&mut fmt::Formatter) -> fmt::Result, |
125 | do_len: impl FnOnce() -> usize, |
126 | ) -> fmt::Result { |
127 | let min_width = match formatter.width() { |
128 | Some(min_width) => min_width, |
129 | None => return do_display(formatter), |
130 | }; |
131 | |
132 | let len = do_len(); |
133 | if len >= min_width { |
134 | return do_display(formatter); |
135 | } |
136 | |
137 | let default_align = Alignment::Left; |
138 | let align = formatter.align().unwrap_or(default_align); |
139 | let padding = min_width - len; |
140 | let (pre_pad, post_pad) = match align { |
141 | Alignment::Left => (0, padding), |
142 | Alignment::Right => (padding, 0), |
143 | Alignment::Center => (padding / 2, (padding + 1) / 2), |
144 | }; |
145 | |
146 | let fill = formatter.fill(); |
147 | for _ in 0..pre_pad { |
148 | formatter.write_char(fill)?; |
149 | } |
150 | |
151 | do_display(formatter)?; |
152 | |
153 | for _ in 0..post_pad { |
154 | formatter.write_char(fill)?; |
155 | } |
156 | Ok(()) |
157 | } |
158 | |
159 | fn digits(val: u64) -> usize { |
160 | if val < 10 { |
161 | 1 |
162 | } else { |
163 | 1 + digits(val:val / 10) |
164 | } |
165 | } |
166 | |