diff --git a/Cargo.lock b/Cargo.lock index 173d06e18..a64da6fcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,15 +74,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5d78ce20460b82d3fa150275ed9d55e21064fc7951177baacf86a145c4a4b1f" -[[package]] -name = "arrayvec" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -dependencies = [ - "nodrop", -] - [[package]] name = "arrayvec" version = "0.7.2" @@ -402,7 +393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb6f80f92629b81f5b17b616a99f72870556ca457bbbd99aeda7bb5d194316a2" dependencies = [ "castaway", - "itoa 1.0.3", + "itoa", "ryu", ] @@ -413,7 +404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5138945395949e7dfba09646dc9e766b548ff48e23deb5246890e6b64ae9e1b9" dependencies = [ "castaway", - "itoa 1.0.3", + "itoa", "ryu", ] @@ -839,7 +830,7 @@ dependencies = [ "bstr 1.0.1", "btoi", "git-date 0.2.0", - "itoa 1.0.3", + "itoa", "nom", "quick-error", ] @@ -853,7 +844,7 @@ dependencies = [ "bstr 1.0.1", "btoi", "git-date 0.3.0", - "itoa 1.0.3", + "itoa", "nom", "quick-error", ] @@ -983,7 +974,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37881e9725df41e15d16216d3a0cee251fd8a39d425f75b389112df5c7f20f3d" dependencies = [ "bstr 1.0.1", - "itoa 1.0.3", + "itoa", "thiserror", "time", ] @@ -995,7 +986,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33db9f4462b565a33507aee113f3383bf16b988d2c573f07691e34302b7aa0a" dependencies = [ "bstr 1.0.1", - "itoa 1.0.3", + "itoa", "thiserror", "time", ] @@ -1140,7 +1131,7 @@ dependencies = [ "git-hash 0.9.11", "git-object 0.21.0", "git-traverse 0.17.0", - "itoa 1.0.3", + "itoa", "memmap2 0.5.3", "smallvec", "thiserror", @@ -1162,7 +1153,7 @@ dependencies = [ "git-lock 3.0.0", "git-object 0.23.0", "git-traverse 0.19.0", - "itoa 1.0.3", + "itoa", "memmap2 0.5.3", "smallvec", "thiserror", @@ -1214,7 +1205,7 @@ dependencies = [ "git-hash 0.9.11", "git-validate 0.6.0", "hex", - "itoa 1.0.3", + "itoa", "nom", "smallvec", "thiserror", @@ -1233,7 +1224,7 @@ dependencies = [ "git-hash 0.10.0", "git-validate 0.7.0", "hex", - "itoa 1.0.3", + "itoa", "nom", "smallvec", "thiserror", @@ -1897,15 +1888,9 @@ checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" [[package]] name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "jobserver" @@ -2103,12 +2088,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "nom" version = "7.1.1" @@ -2132,12 +2111,12 @@ dependencies = [ [[package]] name = "num-format" -version = "0.4.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.4.12", - "itoa 0.4.8", + "arrayvec", + "itoa", ] [[package]] @@ -2223,6 +2202,7 @@ dependencies = [ "image", "insta", "lazy_static", + "num-format", "onefetch-image", "onefetch-manifest", "owo-colors", @@ -2776,7 +2756,7 @@ version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ - "itoa 1.0.3", + "itoa", "ryu", "serde", ] @@ -2788,7 +2768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da" dependencies = [ "indexmap", - "itoa 1.0.3", + "itoa", "ryu", "serde", "unsafe-libyaml", @@ -3060,7 +3040,7 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ - "itoa 1.0.3", + "itoa", "libc", "num_threads", "serde", @@ -3162,7 +3142,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "794a32261a1f5eb6a4462c81b59cec87b5c27d5deea7dd1ac8fc781c41d226db" dependencies = [ - "arrayvec 0.7.2", + "arrayvec", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be015b0cf..d664d2060 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ git-repository = { version = "0.29.0", default-features = false, features = [ git2 = { version = "0.15.0", default-features = false } human-panic = "1.0.3" image = "0.24.4" +num-format = "0.4.4" onefetch-image = { path = "image", version = "2.13.2" } onefetch-manifest = { path = "manifest", version = "2.13.2" } owo-colors = "3.5.0" diff --git a/src/cli.rs b/src/cli.rs index 4cf9fe129..5b26c2adc 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -6,9 +6,11 @@ use clap::builder::PossibleValuesParser; use clap::builder::TypedValueParser as _; use clap::{value_parser, Command, Parser, ValueHint}; use clap_complete::{generate, Generator, Shell}; +use num_format::CustomFormat; use onefetch_image::ImageProtocol; use onefetch_manifest::ManifestType; use regex::Regex; +use serde::Serialize; use std::env; use std::io; use std::path::PathBuf; @@ -125,7 +127,7 @@ pub struct Config { /// '--text-colors 9 10 11 12 13 14' #[arg( long, - short = 't', + short, value_name = "X", value_parser = value_parser!(u8).range(..16), num_args = 1..=6 @@ -134,6 +136,9 @@ pub struct Config { /// Use ISO 8601 formatted timestamps #[arg(long, short = 'z')] pub iso_time: bool, + /// Which thousands SEPARATOR to use + #[arg(long, value_name = "SEPARATOR", default_value = "plain", value_enum)] + pub number_separator: NumberSeparator, /// Show the email address of each author #[arg(long, short = 'E')] pub email: bool, @@ -179,6 +184,7 @@ impl Default for Config { show_logo: When::Always, text_colors: Default::default(), iso_time: Default::default(), + number_separator: NumberSeparator::Plain, email: Default::default(), include_hidden: Default::default(), r#type: vec![LanguageType::Programming, LanguageType::Markup], @@ -229,6 +235,33 @@ pub enum When { Always, } +#[derive(clap::ValueEnum, Clone, PartialEq, Eq, Debug, Serialize, Copy)] +pub enum NumberSeparator { + Plain, + Comma, + Space, + Underscore, +} + +impl NumberSeparator { + fn separator(&self) -> &'static str { + match self { + Self::Plain => "", + Self::Comma => ",", + Self::Space => "\u{202f}", + Self::Underscore => "_", + } + } + + pub fn get_format(&self) -> CustomFormat { + num_format::CustomFormat::builder() + .grouping(num_format::Grouping::Standard) + .separator(self.separator()) + .build() + .unwrap() + } +} + #[cfg(test)] mod test { use super::*; diff --git a/src/info/git.rs b/src/info/git.rs index cfe2affb9..c71ec7855 100644 --- a/src/info/git.rs +++ b/src/info/git.rs @@ -1,5 +1,5 @@ use super::repo::author::Author; -use crate::cli::MyRegex; +use crate::cli::{MyRegex, NumberSeparator}; use anyhow::Result; use git::bstr::BString; use git_repository as git; @@ -35,6 +35,7 @@ impl Commits { bot_regex_pattern: &Option, number_of_authors_to_display: usize, show_email: bool, + number_separator: NumberSeparator, ) -> Result { // assure that objects we just traversed are coming from cache // when we read the commit right after. @@ -93,6 +94,7 @@ impl Commits { author_nbr_of_commits, total_nbr_of_commits, show_email, + number_separator, ) }) .take(number_of_authors_to_display) diff --git a/src/info/mod.rs b/src/info/mod.rs index 1c72047ce..8c9a815b1 100644 --- a/src/info/mod.rs +++ b/src/info/mod.rs @@ -18,10 +18,11 @@ use self::repo::size::SizeInfo; use self::repo::url::UrlInfo; use self::repo::version::VersionInfo; use self::title::Title; -use crate::cli::{is_truecolor_terminal, Config, MyRegex, When}; +use crate::cli::{is_truecolor_terminal, Config, MyRegex, NumberSeparator, When}; use crate::ui::get_ascii_colors; use crate::ui::text_colors::TextColors; use anyhow::{Context, Result}; +use num_format::ToFormattedString; use onefetch_manifest::Manifest; use owo_colors::{DynColors, OwoColorize, Style}; use regex::Regex; @@ -245,10 +246,15 @@ impl Info { let description = DescriptionInfo::new(manifest.as_ref()); let pending = PendingInfo::new(&git_repo)?; let repo_url = UrlInfo::new(&git_repo)?; - let project = ProjectInfo::new(&git_repo, &repo_url.repo_url, manifest.as_ref())?; + let project = ProjectInfo::new( + &git_repo, + &repo_url.repo_url, + manifest.as_ref(), + config.number_separator, + )?; let head = HeadInfo::new(&git_repo)?; let version = VersionInfo::new(&git_repo, manifest.as_ref())?; - let size = SizeInfo::new(&git_repo); + let size = SizeInfo::new(&git_repo, config.number_separator); let license = LicenseInfo::new(&repo_path, manifest.as_ref())?; let mut commits = Commits::new( git_repo, @@ -256,6 +262,7 @@ impl Info { &no_bots, config.number_of_authors, config.email, + config.number_separator, )?; let created = CreatedInfo::new(config.iso_time, &commits); let languages = LanguagesInfo::new( @@ -264,12 +271,13 @@ impl Info { config.number_of_languages, text_colors.info, ); - let dependencies = DependenciesInfo::new(manifest.as_ref()); + let dependencies = DependenciesInfo::new(manifest.as_ref(), config.number_separator); let authors = AuthorsInfo::new(text_colors.info, &mut commits); let last_change = LastChangeInfo::new(config.iso_time, &commits); - let contributors = ContributorsInfo::new(&commits, config.number_of_authors); - let commits = CommitsInfo::new(&commits); - let lines_of_code = LocInfo { lines_of_code }; + let contributors = + ContributorsInfo::new(&commits, config.number_of_authors, config.number_separator); + let commits = CommitsInfo::new(&commits, config.number_separator); + let lines_of_code = LocInfo::new(lines_of_code, config.number_separator); Ok(Self { title, @@ -343,6 +351,13 @@ impl Info { } } +fn format_number( + number: T, + number_separator: NumberSeparator, +) -> String { + number.to_formatted_string(&number_separator.get_format()) +} + fn get_style(is_bold: bool, color: DynColors) -> Style { let mut style = Style::new().color(color); if is_bold { @@ -400,4 +415,21 @@ mod tests { assert_eq!(style, Style::new().color(DynColors::Ansi(AnsiColors::Cyan))); Ok(()) } + + #[test] + fn test_format_number() { + assert_eq!( + &format_number(1_000_000, NumberSeparator::Comma), + "1,000,000" + ); + assert_eq!( + &format_number(1_000_000, NumberSeparator::Space), + "1\u{202f}000\u{202f}000" + ); + assert_eq!( + &format_number(1_000_000, NumberSeparator::Underscore), + "1_000_000" + ); + assert_eq!(&format_number(1_000_000, NumberSeparator::Plain), "1000000"); + } } diff --git a/src/info/repo/author.rs b/src/info/repo/author.rs index 6ce57c963..9aff2d8fe 100644 --- a/src/info/repo/author.rs +++ b/src/info/repo/author.rs @@ -1,6 +1,10 @@ -use crate::info::{ - git::Commits, - info_field::{InfoField, InfoType}, +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + git::Commits, + info_field::{InfoField, InfoType}, + }, }; use git_repository as git; use owo_colors::{DynColors, OwoColorize}; @@ -15,6 +19,8 @@ pub struct Author { contribution: usize, #[serde(skip_serializing)] show_email: bool, + #[serde(skip_serializing)] + number_separator: NumberSeparator, } impl Author { @@ -24,6 +30,7 @@ impl Author { nbr_of_commits: usize, total_nbr_of_commits: usize, show_email: bool, + number_separator: NumberSeparator, ) -> Self { let contribution = (nbr_of_commits as f32 * 100. / total_nbr_of_commits as f32).round() as usize; @@ -33,6 +40,7 @@ impl Author { nbr_of_commits, contribution, show_email, + number_separator, } } } @@ -43,13 +51,18 @@ impl std::fmt::Display for Author { write!( f, "{}% {} <{}> {}", - self.contribution, self.name, self.email, self.nbr_of_commits + self.contribution, + self.name, + self.email, + format_number(self.nbr_of_commits, self.number_separator) ) } else { write!( f, "{}% {} {}", - self.contribution, self.name, self.nbr_of_commits + self.contribution, + self.name, + format_number(self.nbr_of_commits, self.number_separator) ) } } @@ -118,6 +131,7 @@ mod test { 1500, 2000, true, + NumberSeparator::Plain, ); assert_eq!(author.to_string(), "75% John Doe 1500"); @@ -131,6 +145,7 @@ mod test { 1500, 2000, false, + NumberSeparator::Plain, ); assert_eq!(author.to_string(), "75% John Doe 1500"); @@ -144,6 +159,7 @@ mod test { 1500, 2000, true, + NumberSeparator::Plain, ); let authors_info = AuthorsInfo { @@ -162,6 +178,7 @@ mod test { 1500, 2000, true, + NumberSeparator::Plain, ); let author_2 = Author::new( @@ -170,6 +187,7 @@ mod test { 240, 300, false, + NumberSeparator::Plain, ); let authors_info = AuthorsInfo { @@ -188,6 +206,7 @@ mod test { 1500, 2000, true, + NumberSeparator::Plain, ); let authors_info = AuthorsInfo { @@ -211,6 +230,7 @@ mod test { 1500, 2000, true, + NumberSeparator::Plain, ); let author_2 = Author::new( @@ -219,6 +239,7 @@ mod test { 240, 300, false, + NumberSeparator::Plain, ); let authors_info = AuthorsInfo { diff --git a/src/info/repo/commits.rs b/src/info/repo/commits.rs index 0f3eb77d9..dd706c10b 100644 --- a/src/info/repo/commits.rs +++ b/src/info/repo/commits.rs @@ -1,31 +1,37 @@ -use crate::info::{ - git::Commits, - info_field::{InfoField, InfoType}, +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + git::Commits, + info_field::{InfoField, InfoType}, + }, }; pub struct CommitsInfo { - pub number_of_commits: String, + pub number_of_commits: usize, + is_shallow: bool, + number_separator: NumberSeparator, } impl CommitsInfo { - pub fn new(commits: &Commits) -> Self { - let number_of_commits = number_of_commits(commits); - Self { number_of_commits } + pub fn new(commits: &Commits, number_separator: NumberSeparator) -> Self { + Self { + number_of_commits: commits.num_commits, + is_shallow: commits.is_shallow, + number_separator, + } } } -fn number_of_commits(commits: &Commits) -> String { - format!( - "{}{}", - commits.num_commits, - commits.is_shallow.then(|| " (shallow)").unwrap_or_default() - ) -} impl InfoField for CommitsInfo { const TYPE: InfoType = InfoType::Commits; fn value(&self) -> String { - self.number_of_commits.to_string() + format!( + "{}{}", + format_number(self.number_of_commits, self.number_separator), + self.is_shallow.then(|| " (shallow)").unwrap_or_default() + ) } fn title(&self) -> String { @@ -40,7 +46,9 @@ mod test { #[test] fn test_display_commits_info() { let commits_info = CommitsInfo { - number_of_commits: "3".to_string(), + number_of_commits: 3, + is_shallow: false, + number_separator: NumberSeparator::Plain, }; assert_eq!(commits_info.value(), "3".to_string()); @@ -48,20 +56,12 @@ mod test { #[test] fn test_display_commits_info_shallow() { - use crate::info::git::Commits; - use git_repository::actor::Time; - - let timestamp = Time::now_utc(); - let commits = Commits { - authors: vec![], - total_num_authors: 0, - num_commits: 2, + let commits_info = CommitsInfo { + number_of_commits: 2, is_shallow: true, - time_of_most_recent_commit: timestamp, - time_of_first_commit: timestamp, + number_separator: NumberSeparator::Plain, }; - let info = CommitsInfo::new(&commits); - assert_eq!(info.value(), "2 (shallow)".to_string()); + assert_eq!(commits_info.value(), "2 (shallow)".to_string()); } } diff --git a/src/info/repo/contributors.rs b/src/info/repo/contributors.rs index c27526664..a56185f2d 100644 --- a/src/info/repo/contributors.rs +++ b/src/info/repo/contributors.rs @@ -1,18 +1,28 @@ -use crate::info::{ - git::Commits, - info_field::{InfoField, InfoType}, +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + git::Commits, + info_field::{InfoField, InfoType}, + }, }; pub struct ContributorsInfo { pub number_of_contributors: usize, pub number_of_authors_to_display: usize, + number_separator: NumberSeparator, } impl ContributorsInfo { - pub fn new(commits: &Commits, number_of_authors_to_display: usize) -> Self { + pub fn new( + commits: &Commits, + number_of_authors_to_display: usize, + number_separator: NumberSeparator, + ) -> Self { let contributors = number_of_contributors(commits); Self { number_of_contributors: contributors, number_of_authors_to_display, + number_separator, } } } @@ -26,7 +36,7 @@ impl InfoField for ContributorsInfo { fn value(&self) -> String { if self.number_of_contributors > self.number_of_authors_to_display { - self.number_of_contributors.to_string() + format_number(self.number_of_contributors, self.number_separator) } else { "".to_string() } @@ -56,7 +66,7 @@ mod test { time_of_first_commit: timestamp, }; - let contributors_info = ContributorsInfo::new(&commits, 2); + let contributors_info = ContributorsInfo::new(&commits, 2, NumberSeparator::Plain); assert_eq!(contributors_info.value(), "12".to_string()); assert_eq!(contributors_info.title(), "Contributors".to_string()); } @@ -66,6 +76,7 @@ mod test { let contributors_info = ContributorsInfo { number_of_contributors: 1, number_of_authors_to_display: 3, + number_separator: NumberSeparator::Plain, }; assert!(contributors_info.value().is_empty()); diff --git a/src/info/repo/dependencies.rs b/src/info/repo/dependencies.rs index d5dcd2918..b9c8cf6fb 100644 --- a/src/info/repo/dependencies.rs +++ b/src/info/repo/dependencies.rs @@ -1,4 +1,10 @@ -use crate::info::info_field::{InfoField, InfoType}; +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + info_field::{InfoField, InfoType}, + }, +}; use onefetch_manifest::Manifest; pub struct DependenciesInfo { @@ -6,11 +12,16 @@ pub struct DependenciesInfo { } impl DependenciesInfo { - pub fn new(manifest: Option<&Manifest>) -> Self { + pub fn new(manifest: Option<&Manifest>, number_separator: NumberSeparator) -> Self { let dependencies = manifest .and_then(|m| { - (m.number_of_dependencies != 0) - .then(|| format!("{} ({})", m.number_of_dependencies, m.manifest_type)) + (m.number_of_dependencies != 0).then(|| { + format!( + "{} ({})", + format_number(m.number_of_dependencies, number_separator), + m.manifest_type + ) + }) }) .unwrap_or_default(); @@ -37,14 +48,17 @@ mod test { #[test] fn should_display_license() { - let dependencies_info = DependenciesInfo::new(Some(&Manifest { - manifest_type: ManifestType::Cargo, - name: String::new(), - description: None, - number_of_dependencies: 21, - version: String::new(), - license: None, - })); + let dependencies_info = DependenciesInfo::new( + Some(&Manifest { + manifest_type: ManifestType::Cargo, + name: String::new(), + description: None, + number_of_dependencies: 21, + version: String::new(), + license: None, + }), + NumberSeparator::Plain, + ); assert_eq!(dependencies_info.value(), "21 (Cargo)".to_string()); } diff --git a/src/info/repo/loc.rs b/src/info/repo/loc.rs index e87907a36..0f8e67114 100644 --- a/src/info/repo/loc.rs +++ b/src/info/repo/loc.rs @@ -1,14 +1,30 @@ -use crate::info::info_field::{InfoField, InfoType}; +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + info_field::{InfoField, InfoType}, + }, +}; pub struct LocInfo { pub lines_of_code: usize, + number_separator: NumberSeparator, +} + +impl LocInfo { + pub fn new(lines_of_code: usize, number_separator: NumberSeparator) -> Self { + Self { + lines_of_code, + number_separator, + } + } } impl InfoField for LocInfo { const TYPE: InfoType = InfoType::LinesOfCode; fn value(&self) -> String { - self.lines_of_code.to_string() + format_number(self.lines_of_code, self.number_separator) } fn title(&self) -> String { @@ -24,6 +40,7 @@ mod test { fn test_display_loc_info() { let loc_info = LocInfo { lines_of_code: 1235, + number_separator: NumberSeparator::Plain, }; assert_eq!(loc_info.value(), "1235".to_string()); diff --git a/src/info/repo/project.rs b/src/info/repo/project.rs index 068bdd68c..81d159bc1 100644 --- a/src/info/repo/project.rs +++ b/src/info/repo/project.rs @@ -1,4 +1,10 @@ -use crate::info::info_field::{InfoField, InfoType}; +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + info_field::{InfoField, InfoType}, + }, +}; use anyhow::Result; use git_repository::{bstr::ByteSlice, Repository}; use onefetch_manifest::Manifest; @@ -10,10 +16,17 @@ pub struct ProjectInfo { pub repo_name: String, pub number_of_branches: usize, pub number_of_tags: usize, + #[serde(skip_serializing)] + number_separator: NumberSeparator, } impl ProjectInfo { - pub fn new(repo: &Repository, repo_url: &str, manifest: Option<&Manifest>) -> Result { + pub fn new( + repo: &Repository, + repo_url: &str, + manifest: Option<&Manifest>, + number_separator: NumberSeparator, + ) -> Result { let repo_name = get_repo_name(repo_url, manifest)?; let number_of_branches = get_number_of_branches(repo)?; let number_of_tags = get_number_of_tags(repo)?; @@ -21,6 +34,7 @@ impl ProjectInfo { repo_name, number_of_branches, number_of_tags, + number_separator, }) } } @@ -68,13 +82,19 @@ impl std::fmt::Display for ProjectInfo { let branches_str = match self.number_of_branches { 0 => String::new(), 1 => "1 branch".into(), - _ => format!("{} branches", self.number_of_branches), + _ => format!( + "{} branches", + format_number(self.number_of_branches, self.number_separator) + ), }; let tags_str = match self.number_of_tags { 0 => String::new(), 1 => "1 tag".into(), - _ => format!("{} tags", self.number_of_tags), + _ => format!( + "{} tags", + format_number(self.number_of_tags, self.number_separator) + ), }; if tags_str.is_empty() && branches_str.is_empty() { @@ -110,6 +130,7 @@ mod test { repo_name: "onefetch".to_string(), number_of_branches: 3, number_of_tags: 2, + number_separator: NumberSeparator::Plain, }; assert_eq!( @@ -124,6 +145,7 @@ mod test { repo_name: "onefetch".to_string(), number_of_branches: 0, number_of_tags: 0, + number_separator: NumberSeparator::Plain, }; assert_eq!(project_info.value(), "onefetch".to_string()); @@ -135,6 +157,7 @@ mod test { repo_name: "onefetch".to_string(), number_of_branches: 3, number_of_tags: 0, + number_separator: NumberSeparator::Plain, }; assert_eq!(project_info.value(), "onefetch (3 branches)".to_string()); @@ -146,6 +169,7 @@ mod test { repo_name: "onefetch".to_string(), number_of_branches: 0, number_of_tags: 2, + number_separator: NumberSeparator::Plain, }; assert_eq!(project_info.value(), "onefetch (2 tags)".to_string()); @@ -157,6 +181,7 @@ mod test { repo_name: "onefetch".to_string(), number_of_branches: 1, number_of_tags: 1, + number_separator: NumberSeparator::Plain, }; assert_eq!( @@ -179,6 +204,7 @@ mod test { repo_name: "".to_string(), number_of_branches: 0, number_of_tags: 0, + number_separator: NumberSeparator::Plain, }; assert!(project_info.value().is_empty()); diff --git a/src/info/repo/size.rs b/src/info/repo/size.rs index 3ec4fefa1..3353243cb 100644 --- a/src/info/repo/size.rs +++ b/src/info/repo/size.rs @@ -1,18 +1,26 @@ -use crate::info::info_field::{InfoField, InfoType}; +use crate::{ + cli::NumberSeparator, + info::{ + format_number, + info_field::{InfoField, InfoType}, + }, +}; use byte_unit::Byte; use git_repository::Repository; pub struct SizeInfo { pub repo_size: String, pub file_count: u64, + number_separator: NumberSeparator, } impl SizeInfo { - pub fn new(repo: &Repository) -> Self { + pub fn new(repo: &Repository, number_separator: NumberSeparator) -> Self { let (repo_size, file_count) = get_repo_size(repo); Self { repo_size, file_count, + number_separator, } } } @@ -40,7 +48,12 @@ impl std::fmt::Display for SizeInfo { 0 => write!(f, "{}", &self.repo_size), 1 => write!(f, "{} (1 file)", self.repo_size), _ => { - write!(f, "{} ({} files)", self.repo_size, self.file_count) + write!( + f, + "{} ({} files)", + self.repo_size, + format_number(self.file_count, self.number_separator) + ) } } } @@ -66,6 +79,7 @@ mod test { let size_info = SizeInfo { repo_size: "2.40 MiB".to_string(), file_count: 123, + number_separator: NumberSeparator::Plain, }; assert_eq!(size_info.value(), "2.40 MiB (123 files)".to_string()); @@ -76,6 +90,7 @@ mod test { let size_info = SizeInfo { repo_size: "2.40 MiB".to_string(), file_count: 0, + number_separator: NumberSeparator::Plain, }; assert_eq!(size_info.value(), "2.40 MiB".to_string()); @@ -86,6 +101,7 @@ mod test { let size_info = SizeInfo { repo_size: "2.40 MiB".to_string(), file_count: 1, + number_separator: NumberSeparator::Plain, }; assert_eq!(size_info.value(), "2.40 MiB (1 file)".to_string()); diff --git a/tests/snapshots/repo__repo.snap b/tests/snapshots/repo__repo.snap index 47a8bd755..c3939574a 100644 --- a/tests/snapshots/repo__repo.snap +++ b/tests/snapshots/repo__repo.snap @@ -49,7 +49,7 @@ expression: info "lastChange": "22 years ago", "contributors": 4, "repoUrl": "https://github.com/user/repo.git", - "numberOfCommits": "4", + "numberOfCommits": 4, "linesOfCode": 4, "repoSize": "22 B", "license": "MIT"