From b30e6f8be732dc70e2a0492b3b72bc8a3c246905 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 22 Jun 2025 00:59:44 +0200 Subject: [PATCH] l10n: port df for translation + add french --- .../workspace.wordlist.txt | 1 + src/uu/df/locales/en-US.ftl | 50 ++++++++++ src/uu/df/locales/fr-FR.ftl | 60 ++++++++++++ src/uu/df/src/df.rs | 96 +++++++++++-------- src/uu/df/src/table.rs | 76 +++++++++++---- 5 files changed, 222 insertions(+), 61 deletions(-) create mode 100644 src/uu/df/locales/fr-FR.ftl diff --git a/.vscode/cspell.dictionaries/workspace.wordlist.txt b/.vscode/cspell.dictionaries/workspace.wordlist.txt index bbdb82519..d4a7b52fb 100644 --- a/.vscode/cspell.dictionaries/workspace.wordlist.txt +++ b/.vscode/cspell.dictionaries/workspace.wordlist.txt @@ -25,6 +25,7 @@ getrandom globset indicatif itertools +iuse langid lscolors mdbook diff --git a/src/uu/df/locales/en-US.ftl b/src/uu/df/locales/en-US.ftl index cbc69df76..62bff44d8 100644 --- a/src/uu/df/locales/en-US.ftl +++ b/src/uu/df/locales/en-US.ftl @@ -8,3 +8,53 @@ df-after-help = Display values are in units of the first available SIZE from --b SIZE is an integer and optional unit (example: 10M is 10*1024*1024). Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB,... (powers of 1000). + +# Help messages +df-help-print-help = Print help information. +df-help-all = include dummy file systems +df-help-block-size = scale sizes by SIZE before printing them; e.g. '-BM' prints sizes in units of 1,048,576 bytes +df-help-total = produce a grand total +df-help-human-readable = print sizes in human readable format (e.g., 1K 234M 2G) +df-help-si = likewise, but use powers of 1000 not 1024 +df-help-inodes = list inode information instead of block usage +df-help-kilo = like --block-size=1K +df-help-local = limit listing to local file systems +df-help-no-sync = do not invoke sync before getting usage info (default) +df-help-output = use output format defined by FIELD_LIST, or print all fields if FIELD_LIST is omitted. +df-help-portability = use the POSIX output format +df-help-sync = invoke sync before getting usage info (non-windows only) +df-help-type = limit listing to file systems of type TYPE +df-help-print-type = print file system type +df-help-exclude-type = limit listing to file systems not of type TYPE + +# Error messages +df-error-block-size-too-large = --block-size argument '{ $size }' too large +df-error-invalid-block-size = invalid --block-size argument { $size } +df-error-invalid-suffix = invalid suffix in --block-size argument { $size } +df-error-field-used-more-than-once = option --output: field { $field } used more than once +df-error-filesystem-type-both-selected-and-excluded = file system type { $type } both selected and excluded +df-error-no-such-file-or-directory = { $path }: No such file or directory +df-error-no-file-systems-processed = no file systems processed +df-error-cannot-access-over-mounted = cannot access { $path }: over-mounted by another device +df-error-cannot-read-table-of-mounted-filesystems = cannot read table of mounted file systems +df-error-inodes-not-supported-windows = { $program }: doesn't support -i option + +# Headers +df-header-filesystem = Filesystem +df-header-size = Size +df-header-used = Used +df-header-avail = Avail +df-header-available = Available +df-header-use-percent = Use% +df-header-capacity = Capacity +df-header-mounted-on = Mounted on +df-header-inodes = Inodes +df-header-iused = IUsed +df-header-iavail = IFree +df-header-iuse-percent = IUse% +df-header-file = File +df-header-type = Type + +# Other +df-total = total +df-blocks-suffix = -blocks diff --git a/src/uu/df/locales/fr-FR.ftl b/src/uu/df/locales/fr-FR.ftl new file mode 100644 index 000000000..f7c8236da --- /dev/null +++ b/src/uu/df/locales/fr-FR.ftl @@ -0,0 +1,60 @@ +df-about = afficher des informations sur le système de fichiers sur lequel chaque FICHIER réside, + ou tous les systèmes de fichiers par défaut. +df-usage = df [OPTION]... [FICHIER]... +df-after-help = Les valeurs affichées sont en unités de la première TAILLE disponible de --block-size, + et des variables d'environnement DF_BLOCK_SIZE, BLOCK_SIZE et BLOCKSIZE. + Sinon, les unités par défaut sont 1024 octets (ou 512 si POSIXLY_CORRECT est défini). + + TAILLE est un entier et une unité optionnelle (exemple : 10M est 10*1024*1024). + Les unités sont K, M, G, T, P, E, Z, Y (puissances de 1024) ou KB, MB,... (puissances + de 1000). + +# Messages d'aide +df-help-print-help = afficher les informations d'aide. +df-help-all = inclure les systèmes de fichiers factices +df-help-block-size = mettre les tailles à l'échelle par TAILLE avant de les afficher ; par ex. '-BM' affiche les tailles en unités de 1 048 576 octets +df-help-total = produire un total général +df-help-human-readable = afficher les tailles dans un format lisible par l'homme (par ex., 1K 234M 2G) +df-help-si = pareillement, mais utiliser les puissances de 1000 pas 1024 +df-help-inodes = lister les informations d'inode au lieu de l'utilisation des blocs +df-help-kilo = comme --block-size=1K +df-help-local = limiter l'affichage aux systèmes de fichiers locaux +df-help-no-sync = ne pas invoquer sync avant d'obtenir les informations d'utilisation (par défaut) +df-help-output = utiliser le format de sortie défini par LISTE_CHAMPS, ou afficher tous les champs si LISTE_CHAMPS est omise. +df-help-portability = utiliser le format de sortie POSIX +df-help-sync = invoquer sync avant d'obtenir les informations d'utilisation (non-windows seulement) +df-help-type = limiter l'affichage aux systèmes de fichiers de type TYPE +df-help-print-type = afficher le type de système de fichiers +df-help-exclude-type = limiter l'affichage aux systèmes de fichiers pas de type TYPE + +# Messages d'erreur +df-error-block-size-too-large = argument --block-size '{ $size }' trop grand +df-error-invalid-block-size = argument --block-size invalide { $size } +df-error-invalid-suffix = suffixe invalide dans l'argument --block-size { $size } +df-error-field-used-more-than-once = option --output : champ { $field } utilisé plus d'une fois +df-error-filesystem-type-both-selected-and-excluded = type de système de fichiers { $type } à la fois sélectionné et exclu +df-error-no-such-file-or-directory = { $path } : aucun fichier ou répertoire de ce type +df-error-no-file-systems-processed = aucun système de fichiers traité +df-error-cannot-access-over-mounted = impossible d'accéder à { $path } : sur-monté par un autre périphérique +df-error-cannot-read-table-of-mounted-filesystems = impossible de lire la table des systèmes de fichiers montés +df-error-inodes-not-supported-windows = { $program } : ne supporte pas l'option -i + +# En-têtes du tableau +df-header-filesystem = Sys. de fichiers +df-header-size = Taille +df-header-used = Utilisé +df-header-avail = Disp. +df-header-available = Disponible +df-header-use-percent = Util% +df-header-capacity = Capacité +df-header-mounted-on = Monté sur +df-header-inodes = Inodes +df-header-iused = IUtil +df-header-iavail = ILibre +df-header-iuse-percent = IUtil% +df-header-file = Fichier +df-header-type = Type + +# Autres messages +df-total = total +df-blocks-suffix = -blocs diff --git a/src/uu/df/src/df.rs b/src/uu/df/src/df.rs index c346cf163..24dccdae7 100644 --- a/src/uu/df/src/df.rs +++ b/src/uu/df/src/df.rs @@ -29,7 +29,8 @@ use crate::filesystem::Filesystem; use crate::filesystem::FsError; use crate::table::Table; -use uucore::locale::get_message; +use std::collections::HashMap; +use uucore::locale::{get_message, get_message_with_args}; static OPT_HELP: &str = "help"; static OPT_ALL: &str = "all"; @@ -115,25 +116,28 @@ impl Default for Options { enum OptionsError { // TODO This needs to vary based on whether `--block-size` // or `-B` were provided. - #[error("--block-size argument '{0}' too large")] + #[error("{}", get_message_with_args("df-error-block-size-too-large", HashMap::from([("size".to_string(), .0.clone())])))] BlockSizeTooLarge(String), // TODO This needs to vary based on whether `--block-size` // or `-B` were provided., - #[error("invalid --block-size argument {0}")] + #[error("{}", get_message_with_args("df-error-invalid-block-size", HashMap::from([("size".to_string(), .0.clone())])))] InvalidBlockSize(String), // TODO This needs to vary based on whether `--block-size` // or `-B` were provided. - #[error("invalid suffix in --block-size argument {0}")] + #[error("{}", get_message_with_args("df-error-invalid-suffix", HashMap::from([("size".to_string(), .0.clone())])))] InvalidSuffix(String), /// An error getting the columns to display in the output table. - #[error("option --output: field {0} used more than once")] + #[error("{}", get_message_with_args("df-error-field-used-more-than-once", HashMap::from([("field".to_string(), format!("{}", .0))])))] ColumnError(ColumnError), - #[error("{}", .0.iter() - .map(|t| format!("file system type {} both selected and excluded", t.quote())) + #[error( + "{}", + .0.iter() + .map(|t| get_message_with_args("df-error-filesystem-type-both-selected-and-excluded", HashMap::from([("type".to_string(), t.quote().to_string())]))) .collect::>() - .join(format!("\n{}: ", uucore::util_name()).as_str()))] + .join(format!("\n{}: ", uucore::util_name()).as_str()) + )] FilesystemTypeBothSelectedAndExcluded(Vec), } @@ -359,26 +363,35 @@ where Err(FsError::InvalidPath) => { show!(USimpleError::new( 1, - format!("{}: No such file or directory", path.as_ref().display()) + get_message_with_args( + "df-error-no-such-file-or-directory", + HashMap::from([("path".to_string(), path.as_ref().display().to_string())]) + ) )); } Err(FsError::MountMissing) => { - show!(USimpleError::new(1, "no file systems processed")); + show!(USimpleError::new( + 1, + get_message("df-error-no-file-systems-processed") + )); } #[cfg(not(windows))] Err(FsError::OverMounted) => { show!(USimpleError::new( 1, - format!( - "cannot access {}: over-mounted by another device", - path.as_ref().quote() + get_message_with_args( + "df-error-cannot-access-over-mounted", + HashMap::from([("path".to_string(), path.as_ref().quote().to_string())]) ) )); } } } if get_exit_code() == 0 && result.is_empty() { - show!(USimpleError::new(1, "no file systems processed")); + show!(USimpleError::new( + 1, + get_message("df-error-no-file-systems-processed") + )); return Ok(result); } @@ -405,7 +418,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { #[cfg(windows)] { if matches.get_flag(OPT_INODES) { - println!("{}: doesn't support -i option", uucore::util_name()); + println!( + "{}", + get_message_with_args( + "df-error-inodes-not-supported-windows", + HashMap::from([("program".to_string(), uucore::util_name().to_string())]) + ) + ); return Ok(()); } } @@ -415,12 +434,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let filesystems: Vec = match matches.get_many::(OPT_PATHS) { None => { let filesystems = get_all_filesystems(&opt).map_err(|e| { - let context = "cannot read table of mounted file systems"; + let context = get_message("df-error-cannot-read-table-of-mounted-filesystems"); USimpleError::new(e.code(), format!("{context}: {e}")) })?; if filesystems.is_empty() { - return Err(USimpleError::new(1, "no file systems processed")); + return Err(USimpleError::new( + 1, + get_message("df-error-no-file-systems-processed"), + )); } filesystems @@ -428,7 +450,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Some(paths) => { let paths: Vec<_> = paths.collect(); let filesystems = get_named_filesystems(&paths, &opt).map_err(|e| { - let context = "cannot read table of mounted file systems"; + let context = get_message("df-error-cannot-read-table-of-mounted-filesystems"); USimpleError::new(e.code(), format!("{context}: {e}")) })?; @@ -458,7 +480,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(OPT_HELP) .long(OPT_HELP) - .help("Print help information.") + .help(get_message("df-help-print-help")) .action(ArgAction::Help), ) .arg( @@ -466,7 +488,7 @@ pub fn uu_app() -> Command { .short('a') .long("all") .overrides_with(OPT_ALL) - .help("include dummy file systems") + .help(get_message("df-help-all")) .action(ArgAction::SetTrue), ) .arg( @@ -475,16 +497,13 @@ pub fn uu_app() -> Command { .long("block-size") .value_name("SIZE") .overrides_with_all([OPT_KILO, OPT_BLOCKSIZE]) - .help( - "scale sizes by SIZE before printing them; e.g.\ - '-BM' prints sizes in units of 1,048,576 bytes", - ), + .help(get_message("df-help-block-size")), ) .arg( Arg::new(OPT_TOTAL) .long("total") .overrides_with(OPT_TOTAL) - .help("produce a grand total") + .help(get_message("df-help-total")) .action(ArgAction::SetTrue), ) .arg( @@ -492,7 +511,7 @@ pub fn uu_app() -> Command { .short('h') .long("human-readable") .overrides_with_all([OPT_HUMAN_READABLE_DECIMAL, OPT_HUMAN_READABLE_BINARY]) - .help("print sizes in human readable format (e.g., 1K 234M 2G)") + .help(get_message("df-help-human-readable")) .action(ArgAction::SetTrue), ) .arg( @@ -500,7 +519,7 @@ pub fn uu_app() -> Command { .short('H') .long("si") .overrides_with_all([OPT_HUMAN_READABLE_BINARY, OPT_HUMAN_READABLE_DECIMAL]) - .help("likewise, but use powers of 1000 not 1024") + .help(get_message("df-help-si")) .action(ArgAction::SetTrue), ) .arg( @@ -508,13 +527,13 @@ pub fn uu_app() -> Command { .short('i') .long("inodes") .overrides_with(OPT_INODES) - .help("list inode information instead of block usage") + .help(get_message("df-help-inodes")) .action(ArgAction::SetTrue), ) .arg( Arg::new(OPT_KILO) .short('k') - .help("like --block-size=1K") + .help(get_message("df-help-kilo")) .overrides_with_all([OPT_BLOCKSIZE, OPT_KILO]) .action(ArgAction::SetTrue), ) @@ -523,14 +542,14 @@ pub fn uu_app() -> Command { .short('l') .long("local") .overrides_with(OPT_LOCAL) - .help("limit listing to local file systems") + .help(get_message("df-help-local")) .action(ArgAction::SetTrue), ) .arg( Arg::new(OPT_NO_SYNC) .long("no-sync") .overrides_with_all([OPT_SYNC, OPT_NO_SYNC]) - .help("do not invoke sync before getting usage info (default)") + .help(get_message("df-help-no-sync")) .action(ArgAction::SetTrue), ) .arg( @@ -545,24 +564,21 @@ pub fn uu_app() -> Command { .default_missing_values(OUTPUT_FIELD_LIST) .default_values(["source", "size", "used", "avail", "pcent", "target"]) .conflicts_with_all([OPT_INODES, OPT_PORTABILITY, OPT_PRINT_TYPE]) - .help( - "use the output format defined by FIELD_LIST, \ - or print all fields if FIELD_LIST is omitted.", - ), + .help(get_message("df-help-output")), ) .arg( Arg::new(OPT_PORTABILITY) .short('P') .long("portability") .overrides_with(OPT_PORTABILITY) - .help("use the POSIX output format") + .help(get_message("df-help-portability")) .action(ArgAction::SetTrue), ) .arg( Arg::new(OPT_SYNC) .long("sync") .overrides_with_all([OPT_NO_SYNC, OPT_SYNC]) - .help("invoke sync before getting usage info (non-windows only)") + .help(get_message("df-help-sync")) .action(ArgAction::SetTrue), ) .arg( @@ -572,14 +588,14 @@ pub fn uu_app() -> Command { .value_parser(ValueParser::os_string()) .value_name("TYPE") .action(ArgAction::Append) - .help("limit listing to file systems of type TYPE"), + .help(get_message("df-help-type")), ) .arg( Arg::new(OPT_PRINT_TYPE) .short('T') .long("print-type") .overrides_with(OPT_PRINT_TYPE) - .help("print file system type") + .help(get_message("df-help-print-type")) .action(ArgAction::SetTrue), ) .arg( @@ -590,7 +606,7 @@ pub fn uu_app() -> Command { .value_parser(ValueParser::os_string()) .value_name("TYPE") .use_value_delimiter(true) - .help("limit listing to file systems not of type TYPE"), + .help(get_message("df-help-exclude-type")), ) .arg( Arg::new(OPT_PATHS) diff --git a/src/uu/df/src/table.rs b/src/uu/df/src/table.rs index be7eb8557..38fc69c8d 100644 --- a/src/uu/df/src/table.rs +++ b/src/uu/df/src/table.rs @@ -14,6 +14,7 @@ use crate::columns::{Alignment, Column}; use crate::filesystem::Filesystem; use crate::{BlockSize, Options}; use uucore::fsext::{FsUsage, MountInfo}; +use uucore::locale::get_message; use std::fmt; use std::ops::AddAssign; @@ -106,7 +107,7 @@ impl AddAssign for Row { let inodes_used = self.inodes_used + rhs.inodes_used; *self = Self { file: None, - fs_device: "total".into(), + fs_device: get_message("df-total"), fs_type: "-".into(), fs_mount: "-".into(), bytes, @@ -261,7 +262,7 @@ impl<'a> RowFormatter<'a> { let string = match column { Column::Source => { if self.is_total_row { - "total".to_string() + get_message("df-total") } else { self.row.fs_device.to_string() } @@ -273,7 +274,7 @@ impl<'a> RowFormatter<'a> { Column::Target => { if self.is_total_row && !self.options.columns.contains(&Column::Source) { - "total".to_string() + get_message("df-total") } else { self.row.fs_mount.to_string() } @@ -325,32 +326,38 @@ impl Header { for column in &options.columns { let header = match column { - Column::Source => String::from("Filesystem"), + Column::Source => get_message("df-header-filesystem"), Column::Size => match options.header_mode { - HeaderMode::HumanReadable => String::from("Size"), + HeaderMode::HumanReadable => get_message("df-header-size"), HeaderMode::PosixPortability => { - format!("{}-blocks", options.block_size.as_u64()) + format!( + "{}{}", + options.block_size.as_u64(), + get_message("df-blocks-suffix") + ) } - _ => format!("{}-blocks", options.block_size), + _ => format!("{}{}", options.block_size, get_message("df-blocks-suffix")), }, - Column::Used => String::from("Used"), + Column::Used => get_message("df-header-used"), Column::Avail => match options.header_mode { - HeaderMode::HumanReadable | HeaderMode::Output => String::from("Avail"), - _ => String::from("Available"), + HeaderMode::HumanReadable | HeaderMode::Output => { + get_message("df-header-avail") + } + _ => get_message("df-header-available"), }, Column::Pcent => match options.header_mode { - HeaderMode::PosixPortability => String::from("Capacity"), - _ => String::from("Use%"), + HeaderMode::PosixPortability => get_message("df-header-capacity"), + _ => get_message("df-header-use-percent"), }, - Column::Target => String::from("Mounted on"), - Column::Itotal => String::from("Inodes"), - Column::Iused => String::from("IUsed"), - Column::Iavail => String::from("IFree"), - Column::Ipcent => String::from("IUse%"), - Column::File => String::from("File"), - Column::Fstype => String::from("Type"), + Column::Target => get_message("df-header-mounted-on"), + Column::Itotal => get_message("df-header-inodes"), + Column::Iused => get_message("df-header-iused"), + Column::Iavail => get_message("df-header-iavail"), + Column::Ipcent => get_message("df-header-iuse-percent"), + Column::File => get_message("df-header-file"), + Column::Fstype => get_message("df-header-type"), #[cfg(target_os = "macos")] - Column::Capacity => String::from("Capacity"), + Column::Capacity => get_message("df-header-capacity"), }; headers.push(header); @@ -383,7 +390,7 @@ impl Table { // // This accumulator is computed in case we need to display the // total counts in the last row of the table. - let mut total = Row::new("total"); + let mut total = Row::new(&get_message("df-total")); for filesystem in filesystems { // If the filesystem is not empty, or if the options require @@ -471,12 +478,20 @@ impl fmt::Display for Table { mod tests { use std::vec; + use uucore::locale::setup_localization; use crate::blocks::HumanReadable; use crate::columns::Column; use crate::table::{Header, HeaderMode, Row, RowFormatter, Table}; use crate::{BlockSize, Options}; + fn init() { + unsafe { + std::env::set_var("LANG", "C"); + } + let _ = setup_localization("df"); + } + const COLUMNS_WITH_FS_TYPE: [Column; 7] = [ Column::Source, Column::Fstype, @@ -521,7 +536,9 @@ mod tests { #[test] fn test_default_header() { + init(); let options = Options::default(); + assert_eq!( Header::get_headers(&options), vec!( @@ -537,6 +554,7 @@ mod tests { #[test] fn test_header_with_fs_type() { + init(); let options = Options { columns: COLUMNS_WITH_FS_TYPE.to_vec(), ..Default::default() @@ -557,6 +575,7 @@ mod tests { #[test] fn test_header_with_inodes() { + init(); let options = Options { columns: COLUMNS_WITH_INODES.to_vec(), ..Default::default() @@ -576,6 +595,7 @@ mod tests { #[test] fn test_header_with_block_size_1024() { + init(); let options = Options { block_size: BlockSize::Bytes(3 * 1024), ..Default::default() @@ -595,6 +615,7 @@ mod tests { #[test] fn test_human_readable_header() { + init(); let options = Options { header_mode: HeaderMode::HumanReadable, ..Default::default() @@ -607,6 +628,7 @@ mod tests { #[test] fn test_posix_portability_header() { + init(); let options = Options { header_mode: HeaderMode::PosixPortability, ..Default::default() @@ -626,6 +648,7 @@ mod tests { #[test] fn test_output_header() { + init(); let options = Options { header_mode: HeaderMode::Output, ..Default::default() @@ -645,6 +668,7 @@ mod tests { #[test] fn test_row_formatter() { + init(); let options = Options { block_size: BlockSize::Bytes(1), ..Default::default() @@ -669,6 +693,7 @@ mod tests { #[test] fn test_row_formatter_with_fs_type() { + init(); let options = Options { columns: COLUMNS_WITH_FS_TYPE.to_vec(), block_size: BlockSize::Bytes(1), @@ -695,6 +720,7 @@ mod tests { #[test] fn test_row_formatter_with_inodes() { + init(); let options = Options { columns: COLUMNS_WITH_INODES.to_vec(), block_size: BlockSize::Bytes(1), @@ -720,6 +746,7 @@ mod tests { #[test] fn test_row_formatter_with_bytes_and_inodes() { + init(); let options = Options { columns: vec![Column::Size, Column::Itotal], block_size: BlockSize::Bytes(100), @@ -736,6 +763,7 @@ mod tests { #[test] fn test_row_formatter_with_human_readable_si() { + init(); let options = Options { human_readable: Some(HumanReadable::Decimal), columns: COLUMNS_WITH_FS_TYPE.to_vec(), @@ -762,6 +790,7 @@ mod tests { #[test] fn test_row_formatter_with_human_readable_binary() { + init(); let options = Options { human_readable: Some(HumanReadable::Binary), columns: COLUMNS_WITH_FS_TYPE.to_vec(), @@ -788,6 +817,7 @@ mod tests { #[test] fn test_row_formatter_with_round_up_usage() { + init(); let options = Options { columns: vec![Column::Pcent], ..Default::default() @@ -802,6 +832,7 @@ mod tests { #[test] fn test_row_formatter_with_round_up_byte_values() { + init(); fn get_formatted_values(bytes: u64, bytes_used: u64, bytes_avail: u64) -> Vec { let options = Options { block_size: BlockSize::Bytes(1000), @@ -826,6 +857,7 @@ mod tests { #[test] fn test_row_converter_with_invalid_numbers() { + init(); // copy from wsl linux let d = crate::Filesystem { file: None, @@ -857,6 +889,7 @@ mod tests { #[test] fn test_table_column_width_computation_include_total_row() { + init(); let d1 = crate::Filesystem { file: None, mount_info: crate::MountInfo { @@ -915,6 +948,7 @@ mod tests { #[test] fn test_row_accumulation_u64_overflow() { + init(); let total = u64::MAX as u128; let used1 = 3000u128; let used2 = 50000u128;