use super::family::Family;
pub fn clap_version(family: &Family) -> &'static str {
Box::leak(format!("({}) {}", family.crate_name, family.version).into_boxed_str())
}
pub fn line(family: &Family, tool: &str) -> String {
format!("{tool} ({}) {}", family.crate_name, family.version)
}
#[derive(Debug, PartialEq, Eq)]
pub struct Identity {
pub tool: String,
pub crate_name: String,
pub version: String,
}
pub fn parse(output: &str) -> Option<Identity> {
let first = output.lines().next()?.trim();
let (tool, rest) = first.split_once(" (")?;
let (crate_name, version) = rest.split_once(") ")?;
let well_formed = !tool.is_empty()
&& !tool.contains(char::is_whitespace)
&& !crate_name.is_empty()
&& !crate_name.contains(char::is_whitespace)
&& version.split('.').count() >= 3
&& !version.contains(char::is_whitespace);
well_formed.then(|| Identity {
tool: tool.to_string(),
crate_name: crate_name.to_string(),
version: version.to_string(),
})
}
#[cfg(test)]
mod tests {
use super::*;
fn identity(tool: &str, crate_name: &str, version: &str) -> Option<Identity> {
Some(Identity {
tool: tool.into(),
crate_name: crate_name.into(),
version: version.into(),
})
}
#[test]
fn our_shape_is_read() {
assert_eq!(
parse("mkfs.ext4 (am-fs-ext4) 0.6.0\n"),
identity("mkfs.ext4", "am-fs-ext4", "0.6.0")
);
assert_eq!(
parse("img.qcow2 (am-img-qcow2) 0.4.5\ntrailing lines are ignored\n"),
identity("img.qcow2", "am-img-qcow2", "0.4.5")
);
}
#[test]
fn another_package_in_our_shape_is_read_and_names_itself() {
assert_eq!(
parse("mkfs.erofs (erofs-utils) 1.9.1\n"),
identity("mkfs.erofs", "erofs-utils", "1.9.1")
);
}
#[test]
fn other_banners_and_usage_messages_are_nobodys() {
for foreign in [
"mke2fs 1.47.0 (5-Feb-2023)",
"Usage: mkfs.ext4 [-c|-l filename] device",
"mkntfs v2022.10.3 (libntfs-3g)",
"Usage: mkntfs [options] device [number-of-sectors]",
"mkfs.erofs 1.8.10",
"Usage: mkfs.erofs [OPTIONS] FILE SOURCE",
"unsquashfs version 4.6.1 (2023/03/25)",
"btrfs-progs v6.6.3",
"xfs_db version 6.1.0",
"",
"fs.x () 1.2.3",
" (am-fs-x) 1.2.3",
"two words (am-fs-x) 1.2.3",
"fs.x (am fs x) 1.2.3",
"fs.x (am-fs-x) 1.2",
"fs.x (am-fs-x) 1.2.3 beta",
] {
assert_eq!(parse(foreign), None, "{foreign:?}");
}
}
#[test]
fn the_line_clap_prints_is_the_line_parse_reads() {
let family = super::super::Family {
repo: "rust-fs-x",
crate_name: "am-fs-x",
version: "1.2.3",
about: "",
install_hints: &[],
tools: &[],
};
assert_eq!(clap_version(&family), "(am-fs-x) 1.2.3");
assert_eq!(line(&family, "fs.x"), "fs.x (am-fs-x) 1.2.3");
assert_eq!(
parse(&line(&family, "fs.x")),
identity("fs.x", "am-fs-x", "1.2.3")
);
}
}