impl fmt::Display for Atom

This commit is contained in:
John Turner
2025-10-26 01:23:28 -04:00
parent 71379a900b
commit 4d69986e18
3 changed files with 256 additions and 2 deletions

View File

@@ -1,8 +1,14 @@
use core::option::Option;
use core::{
fmt::{self, write},
option::Option,
};
use crate::useflag::UseFlag;
use get::Get;
use itertools::Itertools;
pub mod parsers;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -105,3 +111,243 @@ pub struct Atom {
slot: Option<Slot>,
usedeps: Vec<UseDep>,
}
impl fmt::Display for Blocker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Weak => write!(f, "!"),
Self::Strong => write!(f, "!!"),
}
}
}
impl fmt::Display for VersionOperator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Lt => write!(f, "<"),
Self::Gt => write!(f, ">"),
Self::Eq => write!(f, "="),
Self::LtEq => write!(f, "<="),
Self::GtEq => write!(f, ">="),
Self::Roughly => write!(f, "~"),
}
}
}
impl fmt::Display for Category {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Display for Name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Display for VersionNumber {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Display for VersionSuffixKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Alpha => write!(f, "alpha"),
Self::Beta => write!(f, "beta"),
Self::Pre => write!(f, "pre"),
Self::Rc => write!(f, "rc"),
Self::P => write!(f, "p"),
}
}
}
impl fmt::Display for VersionSuffix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.kind)?;
if let Some(number) = self.number.as_ref() {
write!(f, "{number}")?;
}
Ok(())
}
}
impl fmt::Display for Version {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let numbers = self
.numbers
.iter()
.map(|n| n.get().as_str())
.intersperse(".")
.collect::<String>();
let suffixes = self
.suffixes
.iter()
.map(|s| s.to_string())
.intersperse("_".to_string())
.collect::<String>();
write!(f, "{}", numbers)?;
if let Some(letter) = self.letter {
write!(f, "{letter}")?;
}
if suffixes.len() > 0 {
write!(f, "_{}", suffixes)?;
}
if let Some(rev) = self.rev.as_ref() {
write!(f, "-r{rev}")?;
}
Ok(())
}
}
impl fmt::Display for SlotOperator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Eq => write!(f, "="),
Self::Star => write!(f, "*"),
}
}
}
impl fmt::Display for SlotName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Display for Slot {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(slot) = self.slot.as_ref() {
write!(f, "{slot}")?;
}
if let Some(sub) = self.sub.as_ref() {
write!(f, "/{sub}")?;
}
if let Some(operator) = self.operator.as_ref() {
write!(f, "{operator}")?;
}
Ok(())
}
}
impl fmt::Display for UseDepNegate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Minus => write!(f, "-"),
Self::Exclamation => write!(f, "!"),
}
}
}
impl fmt::Display for UseDepSign {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Enabled => write!(f, "(+)"),
Self::Disabled => write!(f, "(-)"),
}
}
}
impl fmt::Display for UseDepCondition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Eq => write!(f, "="),
Self::Question => write!(f, "?"),
}
}
}
impl fmt::Display for UseDep {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(negate) = self.negate.as_ref() {
write!(f, "{negate}")?;
}
write!(f, "{}", self.flag)?;
if let Some(sign) = self.sign.as_ref() {
write!(f, "{sign}")?;
}
if let Some(condition) = self.condition.as_ref() {
write!(f, "{condition}")?;
}
Ok(())
}
}
impl fmt::Display for Atom {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(blocker) = self.blocker.as_ref() {
write!(f, "{blocker}")?;
}
if let Some(version_operator) = self.version_operator.as_ref() {
write!(f, "{version_operator}")?;
}
write!(f, "{}", self.category)?;
write!(f, "/")?;
write!(f, "{}", self.name)?;
if let Some(version) = self.version.as_ref() {
write!(f, "-{version}")?;
}
if let Some(slot) = self.slot.as_ref() {
write!(f, ":{slot}")?;
}
let usedeps = self
.usedeps
.iter()
.map(|u| u.to_string())
.intersperse(",".to_string())
.collect::<String>();
if !usedeps.is_empty() {
write!(f, "[{usedeps}]")?;
}
Ok(())
}
}
#[cfg(test)]
mod test {
use mon::{Parser, input::InputIter};
use crate::atom::parsers;
#[test]
fn test_version_display() {
let s = "1.0.0_alpha1_beta1-r1";
let version = parsers::version()
.parse_finished(InputIter::new(s))
.unwrap();
assert_eq!(version.to_string().as_str(), s);
}
#[test]
fn test_display_atom() {
let s = "!!>=foo/bar-1.0.0v_alpha1_beta1-r1:slot/sub=[a,b,c]";
let atom = parsers::atom().parse_finished(InputIter::new(s)).unwrap();
assert_eq!(atom.to_string().as_str(), s);
}
}