#![cfg(feature = "testkit")]
#![expect(missing_docs, reason = "tests")]
use std::borrow::Cow;
use std::fmt::{self, Alignment, Display, Formatter};
use custom_display::{CustomDisplay, PrecisionBehavior, assert_consistent_width};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Artifact {
group_id: Cow<'static, str>,
artifact_id: Cow<'static, str>,
version: Cow<'static, str>,
}
impl Artifact {
#[inline]
pub const fn new(group_id: String, artifact_id: String, version: String) -> Self {
Self {
group_id: Cow::Owned(group_id),
artifact_id: Cow::Owned(artifact_id),
version: Cow::Owned(version),
}
}
#[inline]
pub const fn new_static(
group_id: &'static str,
artifact_id: &'static str,
version: &'static str,
) -> Self {
Self {
group_id: Cow::Borrowed(group_id),
artifact_id: Cow::Borrowed(artifact_id),
version: Cow::Borrowed(version),
}
}
#[inline]
pub fn group_id(&self) -> &str {
&self.group_id
}
#[inline]
pub fn artifact_id(&self) -> &str {
&self.artifact_id
}
#[inline]
pub fn version(&self) -> &str {
&self.version
}
fn width_plus_const(&self, fixed: usize) -> usize {
fixed
.strict_add(self.group_id.chars().count())
.strict_add(self.artifact_id.chars().count())
.strict_add(self.version.chars().count())
}
}
impl Display for Artifact {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"Artifact({}, {}, {})",
self.group_id, self.artifact_id, self.version,
)
}
}
pub struct SbtExactDisplay;
impl CustomDisplay for SbtExactDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#""{}" % "{}" % "{}""#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::AutoTruncate
}
#[inline]
fn width_in_chars(&self, value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
Some(value.width_plus_const(12))
}
}
impl Display for SbtExactDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("sbt exact")
}
}
pub struct SbtCrossScalaDisplay;
impl CustomDisplay for SbtCrossScalaDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#""{}" %% "{}" % "{}""#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::AutoTruncate
}
#[inline]
fn width_in_chars(&self, value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
Some(value.width_plus_const(13))
}
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Center
}
}
impl Display for SbtCrossScalaDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("sbt cross Scala version")
}
}
pub struct SbtCrossPlatformDisplay;
impl CustomDisplay for SbtCrossPlatformDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#""{}" %%% "{}" % "{}""#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::AutoTruncate
}
#[inline]
fn width_in_chars(&self, value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
Some(value.width_plus_const(14))
}
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Right
}
}
impl Display for SbtCrossPlatformDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("sbt cross platform")
}
}
pub struct MillExactDisplay;
impl CustomDisplay for MillExactDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#"ivy"{}:{}:{}""#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::Manual
}
#[inline]
fn width_in_chars(&self, value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
Some(value.width_plus_const(7))
}
}
impl Display for MillExactDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Mill exact")
}
}
pub struct MillCrossScalaDisplay;
impl CustomDisplay for MillCrossScalaDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#"ivy"{}::{}:{}""#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::Manual
}
#[inline]
fn width_in_chars(&self, value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
Some(value.width_plus_const(8))
}
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Center
}
}
impl Display for MillCrossScalaDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Mill cross Scala version")
}
}
pub struct GradleGroovyLongDisplay;
impl CustomDisplay for GradleGroovyLongDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"implementation group: '{}', name: '{}', version: '{}'",
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::Manual
}
#[inline]
fn width_in_chars(&self, value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
Some(value.width_plus_const(47))
}
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Right
}
}
impl Display for GradleGroovyLongDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Gradle Groovy long")
}
}
pub struct GradleGroovyShortDisplay;
impl CustomDisplay for GradleGroovyShortDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter) -> fmt::Result {
write!(
f,
"implementation '{}:{}:{}'",
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::AutoTruncate
}
#[inline]
fn width_in_chars(&self, _value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
None }
}
impl Display for GradleGroovyShortDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Gradle Groovy short")
}
}
pub struct GradleKotlinDisplay;
impl CustomDisplay for GradleKotlinDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#"implementation("{}:{}:{}")"#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::AutoTruncate
}
#[inline]
fn width_in_chars(&self, _value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
None }
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Center
}
}
impl Display for GradleKotlinDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Gradle Kotlin")
}
}
pub struct IvyDisplay;
impl CustomDisplay for IvyDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
r#"<dependency org="{}" name="{}" rev="{}"/>"#,
value.group_id(),
value.artifact_id(),
value.version()
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::Manual
}
#[inline]
fn width_in_chars(&self, _value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
None }
#[inline]
fn default_alignment(&self) -> Alignment {
Alignment::Right
}
}
impl Display for IvyDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Ivy")
}
}
pub struct MavenDisplay;
impl CustomDisplay for MavenDisplay {
type Value = Artifact;
#[inline]
fn fmt(&self, value: &Self::Value, f: &mut Formatter<'_>) -> fmt::Result {
writeln!(
f,
"\
<dependency>
<groupId>{}</groupId>
<artifactId>{}</artifactId>
<version>{}</version>
</dependency>",
value.group_id(),
value.artifact_id(),
value.version(),
)
}
#[inline]
fn precision_behavior(&self) -> PrecisionBehavior {
PrecisionBehavior::Manual
}
#[inline]
fn width_in_chars(&self, _value: &Self::Value, _f: &Formatter<'_>) -> Option<usize> {
None
}
#[inline]
fn auto_width_fill_alignment(&self) -> bool {
false
}
}
impl Display for MavenDisplay {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad("Maven")
}
}
fn assert_consistent_width<CD>(value: &Artifact, display: CD)
where
CD: CustomDisplay<Value = Artifact> + Display,
{
assert_consistent_width!(&display, value, "{}");
assert_consistent_width!(&display, value, "{:.6}");
assert_consistent_width!(&display, value, "{:.>10.6}");
assert_consistent_width!(&display, value, "{0:.1$}", 6);
assert_consistent_width!(&display, value, "{:<width$}", width = 7);
}
fn artifacts() -> Vec<Artifact> {
const LGBT_PRINCESS: &'static str = "lgbt.princess";
vec![
Artifact::new_static(LGBT_PRINCESS, "platform", "1.0.2"),
Artifact::new(
"org.example".to_owned(),
"example".to_owned(),
"1.0.0-SNAPSHOT".to_owned(),
),
]
}
#[test]
fn consistent_width() {
for artifact in artifacts() {
assert_consistent_width(&artifact, SbtExactDisplay);
assert_consistent_width(&artifact, SbtCrossScalaDisplay);
assert_consistent_width(&artifact, SbtCrossPlatformDisplay);
assert_consistent_width(&artifact, MillExactDisplay);
assert_consistent_width(&artifact, MillCrossScalaDisplay);
assert_consistent_width(&artifact, GradleGroovyLongDisplay);
assert_consistent_width(&artifact, GradleGroovyShortDisplay);
assert_consistent_width(&artifact, GradleKotlinDisplay);
assert_consistent_width(&artifact, IvyDisplay);
assert_consistent_width(&artifact, MavenDisplay);
assert_consistent_width(&artifact, custom_display::default_non_numeric());
}
}