summaryrefslogtreecommitdiffstats
path: root/third_party/rust/semver/src/display.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/semver/src/display.rs')
-rw-r--r--third_party/rust/semver/src/display.rs165
1 files changed, 165 insertions, 0 deletions
diff --git a/third_party/rust/semver/src/display.rs b/third_party/rust/semver/src/display.rs
new file mode 100644
index 0000000000..3c2871bb97
--- /dev/null
+++ b/third_party/rust/semver/src/display.rs
@@ -0,0 +1,165 @@
+use crate::{BuildMetadata, Comparator, Op, Prerelease, Version, VersionReq};
+use core::fmt::{self, Alignment, Debug, Display, Write};
+
+impl Display for Version {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ 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)
+ }
+}
+
+impl Display for VersionReq {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ if self.comparators.is_empty() {
+ return formatter.write_str("*");
+ }
+ for (i, comparator) in self.comparators.iter().enumerate() {
+ if i > 0 {
+ formatter.write_str(", ")?;
+ }
+ write!(formatter, "{}", comparator)?;
+ }
+ Ok(())
+ }
+}
+
+impl Display for Comparator {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let op = match self.op {
+ Op::Exact => "=",
+ Op::Greater => ">",
+ Op::GreaterEq => ">=",
+ Op::Less => "<",
+ Op::LessEq => "<=",
+ Op::Tilde => "~",
+ Op::Caret => "^",
+ Op::Wildcard => "",
+ #[cfg(no_non_exhaustive)]
+ Op::__NonExhaustive => unreachable!(),
+ };
+ formatter.write_str(op)?;
+ write!(formatter, "{}", self.major)?;
+ if let Some(minor) = &self.minor {
+ write!(formatter, ".{}", minor)?;
+ if let Some(patch) = &self.patch {
+ write!(formatter, ".{}", patch)?;
+ if !self.pre.is_empty() {
+ write!(formatter, "-{}", self.pre)?;
+ }
+ } else if self.op == Op::Wildcard {
+ formatter.write_str(".*")?;
+ }
+ } else if self.op == Op::Wildcard {
+ formatter.write_str(".*")?;
+ }
+ Ok(())
+ }
+}
+
+impl Display for Prerelease {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(self.as_str())
+ }
+}
+
+impl Display for BuildMetadata {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(self.as_str())
+ }
+}
+
+impl Debug for Version {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = formatter.debug_struct("Version");
+ debug
+ .field("major", &self.major)
+ .field("minor", &self.minor)
+ .field("patch", &self.patch);
+ if !self.pre.is_empty() {
+ debug.field("pre", &self.pre);
+ }
+ if !self.build.is_empty() {
+ debug.field("build", &self.build);
+ }
+ debug.finish()
+ }
+}
+
+impl Debug for Prerelease {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "Prerelease(\"{}\")", self)
+ }
+}
+
+impl Debug for BuildMetadata {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ 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)
+ }
+}