Skip to content

Commit

Permalink
Merge pull request #258 from dtolnay/padding
Browse files Browse the repository at this point in the history
Support padding in displaying Version
  • Loading branch information
dtolnay authored Jul 30, 2021
2 parents 9e3d648 + b2d8468 commit f39ca7e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 9 deletions.
79 changes: 70 additions & 9 deletions src/display.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq};
use core::fmt::{self, Debug, Display};
use core::fmt::{self, Alignment, Debug, Display, Write};

impl Display for Version {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)?;
if !self.pre.is_empty() {
write!(formatter, "-{}", self.pre)?;
}
if !self.build.is_empty() {
write!(formatter, "+{}", self.build)?;
}
Ok(())
let do_display = |formatter: &mut fmt::Formatter| -> fmt::Result {
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)?;
if !self.pre.is_empty() {
write!(formatter, "-{}", self.pre)?;
}
if !self.build.is_empty() {
write!(formatter, "+{}", self.build)?;
}
Ok(())
};

let do_len = || -> usize {
digits(self.major)
+ 1
+ digits(self.minor)
+ 1
+ digits(self.patch)
+ !self.pre.is_empty() as usize
+ self.pre.len()
+ !self.build.is_empty() as usize
+ self.build.len()
};

pad(formatter, do_display, do_len)
}
}

Expand Down Expand Up @@ -102,3 +118,48 @@ impl Debug for BuildMetadata {
write!(formatter, "BuildMetadata(\"{}\")", self)
}
}

fn pad(
formatter: &mut fmt::Formatter,
do_display: impl FnOnce(&mut fmt::Formatter) -> fmt::Result,
do_len: impl FnOnce() -> usize,
) -> fmt::Result {
let min_width = match formatter.width() {
Some(min_width) => min_width,
None => return do_display(formatter),
};

let len = do_len();
if len >= min_width {
return do_display(formatter);
}

let default_align = Alignment::Left;
let align = formatter.align().unwrap_or(default_align);
let padding = min_width - len;
let (pre_pad, post_pad) = match align {
Alignment::Left => (0, padding),
Alignment::Right => (padding, 0),
Alignment::Center => (padding / 2, (padding + 1) / 2),
};

let fill = formatter.fill();
for _ in 0..pre_pad {
formatter.write_char(fill)?;
}

do_display(formatter)?;

for _ in 0..post_pad {
formatter.write_char(fill)?;
}
Ok(())
}

fn digits(val: u64) -> usize {
if val < 10 {
1
} else {
1 + digits(val / 10)
}
}
8 changes: 8 additions & 0 deletions tests/test_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,11 @@ fn test_spec_order() {
i += 1;
}
}

#[test]
fn test_align() {
let version = version("1.2.3-rc1");
assert_eq!("1.2.3-rc1 ", format!("{:20}", version));
assert_eq!("*****1.2.3-rc1******", format!("{:*^20}", version));
assert_eq!(" 1.2.3-rc1", format!("{:>20}", version));
}

0 comments on commit f39ca7e

Please sign in to comment.