1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 11:07:44 +00:00

l10n: port numfmt for translation + add french

This commit is contained in:
Sylvestre Ledru 2025-06-17 22:19:45 +02:00
parent f314daff25
commit 6aa4e6d156
5 changed files with 221 additions and 57 deletions

View file

@ -34,3 +34,41 @@ numfmt-after-help = UNIT options:
Optional width value (%10f) will pad output. Optional zero (%010f) width Optional width value (%10f) will pad output. Optional zero (%010f) width
will zero pad the number. Optional negative values (%-10f) will left align. will zero pad the number. Optional negative values (%-10f) will left align.
Optional precision (%.1f) will override the input determined precision. Optional precision (%.1f) will override the input determined precision.
# Help messages
numfmt-help-delimiter = use X instead of whitespace for field delimiter
numfmt-help-field = replace the numbers in these input fields; see FIELDS below
numfmt-help-format = use printf style floating-point FORMAT; see FORMAT below for details
numfmt-help-from = auto-scale input numbers to UNITs; see UNIT below
numfmt-help-from-unit = specify the input unit size
numfmt-help-to = auto-scale output numbers to UNITs; see UNIT below
numfmt-help-to-unit = the output unit size
numfmt-help-padding = pad the output to N characters; positive N will right-align; negative N will left-align; padding is ignored if the output is wider than N; the default is to automatically pad if a whitespace is found
numfmt-help-header = print (without converting) the first N header lines; N defaults to 1 if not specified
numfmt-help-round = use METHOD for rounding when scaling
numfmt-help-suffix = print SUFFIX after each formatted number, and accept inputs optionally ending with SUFFIX
numfmt-help-invalid = set the failure mode for invalid input
numfmt-help-zero-terminated = line delimiter is NUL, not newline
# Error messages
numfmt-error-unsupported-unit = Unsupported unit is specified
numfmt-error-invalid-unit-size = invalid unit size: { $size }
numfmt-error-invalid-padding = invalid padding value { $value }
numfmt-error-invalid-header = invalid header value { $value }
numfmt-error-grouping-cannot-be-combined-with-to = grouping cannot be combined with --to
numfmt-error-delimiter-must-be-single-character = the delimiter must be a single character
numfmt-error-invalid-number-empty = invalid number: ''
numfmt-error-invalid-suffix = invalid suffix in input: { $input }
numfmt-error-invalid-number = invalid number: { $input }
numfmt-error-missing-i-suffix = missing 'i' suffix in input: '{ $number }{ $suffix }' (e.g Ki/Mi/Gi)
numfmt-error-rejecting-suffix = rejecting suffix in input: '{ $number }{ $suffix }' (consider using --from)
numfmt-error-suffix-unsupported-for-unit = This suffix is unsupported for specified unit
numfmt-error-unit-auto-not-supported-with-to = Unit 'auto' isn't supported with --to options
numfmt-error-number-too-big = Number is too big and unsupported
numfmt-error-format-no-percent = format '{ $format }' has no % directive
numfmt-error-format-ends-in-percent = format '{ $format }' ends in %
numfmt-error-invalid-format-directive = invalid format '{ $format }', directive must be %[0]['][-][N][.][N]f
numfmt-error-invalid-format-width-overflow = invalid format '{ $format }' (width overflow)
numfmt-error-invalid-precision = invalid precision in format '{ $format }'
numfmt-error-format-too-many-percent = format '{ $format }' has too many % directives
numfmt-error-unknown-invalid-mode = Unknown invalid mode: { $mode }

View file

@ -0,0 +1,74 @@
numfmt-about = Convertir les nombres vers/depuis des chaînes lisibles par l'homme
numfmt-usage = numfmt [OPTION]... [NOMBRE]...
numfmt-after-help = Options d'UNITÉ :
- none : aucune mise à l'échelle automatique n'est effectuée ; les suffixes déclencheront une erreur
- auto : accepter un suffixe optionnel d'une/deux lettres :
1K = 1000, 1Ki = 1024, 1M = 1000000, 1Mi = 1048576,
- si : accepter un suffixe optionnel d'une lettre :
1K = 1000, 1M = 1000000, ...
- iec : accepter un suffixe optionnel d'une lettre :
1K = 1024, 1M = 1048576, ...
- iec-i : accepter un suffixe optionnel de deux lettres :
1Ki = 1024, 1Mi = 1048576, ...
- FIELDS supporte les plages de champs de style cut(1) :
N N-ième champ, compté à partir de 1
N- du N-ième champ jusqu'à la fin de la ligne
N-M du N-ième au M-ième champ (inclus)
-M du premier au M-ième champ (inclus)
- tous les champs
Plusieurs champs/plages peuvent être séparés par des virgules
FORMAT doit être adapté pour imprimer un argument à virgule flottante %f.
Une guillemet optionnelle (%'f) activera --grouping (si supporté par la locale actuelle).
Une valeur de largeur optionnelle (%10f) remplira la sortie. Un zéro optionnel (%010f)
remplira le nombre de zéros. Des valeurs négatives optionnelles (%-10f) aligneront à gauche.
Une précision optionnelle (%.1f) remplacera la précision déterminée par l'entrée.
# Messages d'aide
numfmt-help-delimiter = utiliser X au lieu d'espaces pour le délimiteur de champ
numfmt-help-field = remplacer les nombres dans ces champs d'entrée ; voir FIELDS ci-dessous
numfmt-help-format = utiliser le FORMAT à virgule flottante de style printf ; voir FORMAT ci-dessous pour les détails
numfmt-help-from = mettre automatiquement à l'échelle les nombres d'entrée vers les UNITÉs ; voir UNIT ci-dessous
numfmt-help-from-unit = spécifier la taille de l'unité d'entrée
numfmt-help-to = mettre automatiquement à l'échelle les nombres de sortie vers les UNITÉs ; voir UNIT ci-dessous
numfmt-help-to-unit = la taille de l'unité de sortie
numfmt-help-padding = remplir la sortie à N caractères ; N positif alignera à droite ; N négatif alignera à gauche ; le remplissage est ignoré si la sortie est plus large que N ; la valeur par défaut est de remplir automatiquement si un espace est trouvé
numfmt-help-header = imprimer (sans convertir) les N premières lignes d'en-tête ; N vaut 1 par défaut si non spécifié
numfmt-help-round = utiliser METHOD pour l'arrondi lors de la mise à l'échelle
numfmt-help-suffix = imprimer SUFFIX après chaque nombre formaté, et accepter les entrées se terminant optionnellement par SUFFIX
numfmt-help-invalid = définir le mode d'échec pour les entrées invalides
numfmt-help-zero-terminated = le délimiteur de ligne est NUL, pas retour à la ligne
# Messages d'erreur
numfmt-error-unsupported-unit = Une unité non supportée est spécifiée
numfmt-error-invalid-unit-size = taille d'unité invalide : { $size }
numfmt-error-invalid-padding = valeur de remplissage invalide { $value }
numfmt-error-invalid-header = valeur d'en-tête invalide { $value }
numfmt-error-grouping-cannot-be-combined-with-to = le groupement ne peut pas être combiné avec --to
numfmt-error-delimiter-must-be-single-character = le délimiteur doit être un seul caractère
numfmt-error-invalid-number-empty = nombre invalide : ''
numfmt-error-invalid-suffix = suffixe invalide dans l'entrée : { $input }
numfmt-error-invalid-number = nombre invalide : { $input }
numfmt-error-missing-i-suffix = suffixe 'i' manquant dans l'entrée : '{ $number }{ $suffix }' (par ex. Ki/Mi/Gi)
numfmt-error-rejecting-suffix = rejet du suffixe dans l'entrée : '{ $number }{ $suffix }' (considérez utiliser --from)
numfmt-error-suffix-unsupported-for-unit = Ce suffixe n'est pas supporté pour l'unité spécifiée
numfmt-error-unit-auto-not-supported-with-to = L'unité 'auto' n'est pas supportée avec les options --to
numfmt-error-number-too-big = Le nombre est trop grand et non supporté
numfmt-error-format-no-percent = le format '{ $format }' n'a pas de directive %
numfmt-error-format-ends-in-percent = le format '{ $format }' se termine par %
numfmt-error-invalid-format-directive = format invalide '{ $format }', la directive doit être %[0]['][-][N][.][N]f
numfmt-error-invalid-format-width-overflow = format invalide '{ $format }' (débordement de largeur)
numfmt-error-invalid-precision = précision invalide dans le format '{ $format }'
numfmt-error-format-too-many-percent = le format '{ $format }' a trop de directives %
numfmt-error-unknown-invalid-mode = Mode invalide inconnu : { $mode }

View file

@ -3,7 +3,9 @@
// For the full copyright and license information, please view the LICENSE // For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code. // file that was distributed with this source code.
// spell-checker:ignore powf // spell-checker:ignore powf
use std::collections::HashMap;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::locale::{get_message, get_message_with_args};
use crate::options::{NumfmtOptions, RoundMethod, TransformOptions}; use crate::options::{NumfmtOptions, RoundMethod, TransformOptions};
use crate::units::{DisplayableSuffix, IEC_BASES, RawSuffix, Result, SI_BASES, Suffix, Unit}; use crate::units::{DisplayableSuffix, IEC_BASES, RawSuffix, Result, SI_BASES, Suffix, Unit};
@ -63,7 +65,7 @@ impl<'a> Iterator for WhitespaceSplitter<'a> {
fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> { fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
if s.is_empty() { if s.is_empty() {
return Err("invalid number: ''".to_string()); return Err(get_message("numfmt-error-invalid-number-empty"));
} }
let with_i = s.ends_with('i'); let with_i = s.ends_with('i');
@ -81,7 +83,12 @@ fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
Some('Z') => Some((RawSuffix::Z, with_i)), Some('Z') => Some((RawSuffix::Z, with_i)),
Some('Y') => Some((RawSuffix::Y, with_i)), Some('Y') => Some((RawSuffix::Y, with_i)),
Some('0'..='9') if !with_i => None, Some('0'..='9') if !with_i => None,
_ => return Err(format!("invalid suffix in input: {}", s.quote())), _ => {
return Err(get_message_with_args(
"numfmt-error-invalid-suffix",
HashMap::from([("input".to_string(), s.quote().to_string())]),
));
}
}; };
let suffix_len = match suffix { let suffix_len = match suffix {
@ -90,9 +97,12 @@ fn parse_suffix(s: &str) -> Result<(f64, Option<Suffix>)> {
Some((_, true)) => 2, Some((_, true)) => 2,
}; };
let number = s[..s.len() - suffix_len] let number = s[..s.len() - suffix_len].parse::<f64>().map_err(|_| {
.parse::<f64>() get_message_with_args(
.map_err(|_| format!("invalid number: {}", s.quote()))?; "numfmt-error-invalid-number",
HashMap::from([("input".to_string(), s.quote().to_string())]),
)
})?;
Ok((number, suffix)) Ok((number, suffix))
} }
@ -132,15 +142,25 @@ fn remove_suffix(i: f64, s: Option<Suffix>, u: &Unit) -> Result<f64> {
RawSuffix::Z => Ok(i * IEC_BASES[7]), RawSuffix::Z => Ok(i * IEC_BASES[7]),
RawSuffix::Y => Ok(i * IEC_BASES[8]), RawSuffix::Y => Ok(i * IEC_BASES[8]),
}, },
(Some((raw_suffix, false)), &Unit::Iec(true)) => Err(format!( (Some((raw_suffix, false)), &Unit::Iec(true)) => Err(get_message_with_args(
"missing 'i' suffix in input: '{i}{raw_suffix:?}' (e.g Ki/Mi/Gi)" "numfmt-error-missing-i-suffix",
HashMap::from([
("number".to_string(), i.to_string()),
("suffix".to_string(), format!("{raw_suffix:?}")),
]),
)), )),
(Some((raw_suffix, with_i)), &Unit::None) => Err(format!( (Some((raw_suffix, with_i)), &Unit::None) => Err(get_message_with_args(
"rejecting suffix in input: '{i}{raw_suffix:?}{}' (consider using --from)", "numfmt-error-rejecting-suffix",
if with_i { "i" } else { "" } HashMap::from([
("number".to_string(), i.to_string()),
(
"suffix".to_string(),
format!("{raw_suffix:?}{}", if with_i { "i" } else { "" }),
),
]),
)), )),
(None, _) => Ok(i), (None, _) => Ok(i),
(_, _) => Err("This suffix is unsupported for specified unit".to_owned()), (_, _) => Err(get_message("numfmt-error-suffix-unsupported-for-unit")),
} }
} }
@ -218,7 +238,7 @@ fn consider_suffix(
let (bases, with_i) = match *u { let (bases, with_i) = match *u {
Unit::Si => (&SI_BASES, false), Unit::Si => (&SI_BASES, false),
Unit::Iec(with_i) => (&IEC_BASES, with_i), Unit::Iec(with_i) => (&IEC_BASES, with_i),
Unit::Auto => return Err("Unit 'auto' isn't supported with --to options".to_owned()), Unit::Auto => return Err(get_message("numfmt-error-unit-auto-not-supported-with-to")),
Unit::None => return Ok((n, None)), Unit::None => return Ok((n, None)),
}; };
@ -232,7 +252,7 @@ fn consider_suffix(
_ if abs_n < bases[7] => 6, _ if abs_n < bases[7] => 6,
_ if abs_n < bases[8] => 7, _ if abs_n < bases[8] => 7,
_ if abs_n < bases[9] => 8, _ if abs_n < bases[9] => 8,
_ => return Err("Number is too big and unsupported".to_string()), _ => return Err(get_message("numfmt-error-number-too-big")),
}; };
let v = if precision > 0 { let v = if precision > 0 {

View file

@ -8,6 +8,7 @@ use crate::format::format_and_print;
use crate::options::*; use crate::options::*;
use crate::units::{Result, Unit}; use crate::units::{Result, Unit};
use clap::{Arg, ArgAction, ArgMatches, Command, parser::ValueSource}; use clap::{Arg, ArgAction, ArgMatches, Command, parser::ValueSource};
use std::collections::HashMap;
use std::io::{BufRead, Error, Write}; use std::io::{BufRead, Error, Write};
use std::result::Result as StdResult; use std::result::Result as StdResult;
use std::str::FromStr; use std::str::FromStr;
@ -15,7 +16,7 @@ use std::str::FromStr;
use units::{IEC_BASES, SI_BASES}; use units::{IEC_BASES, SI_BASES};
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::UResult; use uucore::error::UResult;
use uucore::locale::get_message; use uucore::locale::{get_message, get_message_with_args};
use uucore::parser::shortcut_value_parser::ShortcutValueParser; use uucore::parser::shortcut_value_parser::ShortcutValueParser;
use uucore::ranges::Range; use uucore::ranges::Range;
use uucore::{format_usage, show, show_error}; use uucore::{format_usage, show, show_error};
@ -97,7 +98,7 @@ fn parse_unit(s: &str) -> Result<Unit> {
"iec" => Ok(Unit::Iec(false)), "iec" => Ok(Unit::Iec(false)),
"iec-i" => Ok(Unit::Iec(true)), "iec-i" => Ok(Unit::Iec(true)),
"none" => Ok(Unit::None), "none" => Ok(Unit::None),
_ => Err("Unsupported unit is specified".to_owned()), _ => Err(get_message("numfmt-error-unsupported-unit")),
} }
} }
@ -119,7 +120,10 @@ fn parse_unit_size(s: &str) -> Result<usize> {
} }
} }
Err(format!("invalid unit size: {}", s.quote())) Err(get_message_with_args(
"numfmt-error-invalid-unit-size",
HashMap::from([("size".to_string(), s.quote().to_string())]),
))
} }
// Parses a suffix of a unit size and returns the corresponding multiplier. For example, // Parses a suffix of a unit size and returns the corresponding multiplier. For example,
@ -170,7 +174,12 @@ fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
0 => Err(s), 0 => Err(s),
_ => Ok(n), _ => Ok(n),
}) })
.map_err(|s| format!("invalid padding value {}", s.quote())), .map_err(|s| {
get_message_with_args(
"numfmt-error-invalid-padding",
HashMap::from([("value".to_string(), s.quote().to_string())]),
)
}),
None => Ok(0), None => Ok(0),
}?; }?;
@ -184,7 +193,12 @@ fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
0 => Err(value), 0 => Err(value),
_ => Ok(n), _ => Ok(n),
}) })
.map_err(|value| format!("invalid header value {}", value.quote())) .map_err(|value| {
get_message_with_args(
"numfmt-error-invalid-header",
HashMap::from([("value".to_string(), value.quote().to_string())]),
)
})
} else { } else {
Ok(0) Ok(0)
}?; }?;
@ -206,14 +220,18 @@ fn parse_options(args: &ArgMatches) -> Result<NumfmtOptions> {
}; };
if format.grouping && to != Unit::None { if format.grouping && to != Unit::None {
return Err("grouping cannot be combined with --to".to_string()); return Err(get_message(
"numfmt-error-grouping-cannot-be-combined-with-to",
));
} }
let delimiter = args.get_one::<String>(DELIMITER).map_or(Ok(None), |arg| { let delimiter = args.get_one::<String>(DELIMITER).map_or(Ok(None), |arg| {
if arg.len() == 1 { if arg.len() == 1 {
Ok(Some(arg.to_string())) Ok(Some(arg.to_string()))
} else { } else {
Err("the delimiter must be a single character".to_string()) Err(get_message(
"numfmt-error-delimiter-must-be-single-character",
))
} }
})?; })?;
@ -284,12 +302,12 @@ pub fn uu_app() -> Command {
.short('d') .short('d')
.long(DELIMITER) .long(DELIMITER)
.value_name("X") .value_name("X")
.help("use X instead of whitespace for field delimiter"), .help(get_message("numfmt-help-delimiter")),
) )
.arg( .arg(
Arg::new(FIELD) Arg::new(FIELD)
.long(FIELD) .long(FIELD)
.help("replace the numbers in these input fields; see FIELDS below") .help(get_message("numfmt-help-field"))
.value_name("FIELDS") .value_name("FIELDS")
.allow_hyphen_values(true) .allow_hyphen_values(true)
.default_value(FIELD_DEFAULT), .default_value(FIELD_DEFAULT),
@ -297,56 +315,48 @@ pub fn uu_app() -> Command {
.arg( .arg(
Arg::new(FORMAT) Arg::new(FORMAT)
.long(FORMAT) .long(FORMAT)
.help("use printf style floating-point FORMAT; see FORMAT below for details") .help(get_message("numfmt-help-format"))
.value_name("FORMAT") .value_name("FORMAT")
.allow_hyphen_values(true), .allow_hyphen_values(true),
) )
.arg( .arg(
Arg::new(FROM) Arg::new(FROM)
.long(FROM) .long(FROM)
.help("auto-scale input numbers to UNITs; see UNIT below") .help(get_message("numfmt-help-from"))
.value_name("UNIT") .value_name("UNIT")
.default_value(FROM_DEFAULT), .default_value(FROM_DEFAULT),
) )
.arg( .arg(
Arg::new(FROM_UNIT) Arg::new(FROM_UNIT)
.long(FROM_UNIT) .long(FROM_UNIT)
.help("specify the input unit size") .help(get_message("numfmt-help-from-unit"))
.value_name("N") .value_name("N")
.default_value(FROM_UNIT_DEFAULT), .default_value(FROM_UNIT_DEFAULT),
) )
.arg( .arg(
Arg::new(TO) Arg::new(TO)
.long(TO) .long(TO)
.help("auto-scale output numbers to UNITs; see UNIT below") .help(get_message("numfmt-help-to"))
.value_name("UNIT") .value_name("UNIT")
.default_value(TO_DEFAULT), .default_value(TO_DEFAULT),
) )
.arg( .arg(
Arg::new(TO_UNIT) Arg::new(TO_UNIT)
.long(TO_UNIT) .long(TO_UNIT)
.help("the output unit size") .help(get_message("numfmt-help-to-unit"))
.value_name("N") .value_name("N")
.default_value(TO_UNIT_DEFAULT), .default_value(TO_UNIT_DEFAULT),
) )
.arg( .arg(
Arg::new(PADDING) Arg::new(PADDING)
.long(PADDING) .long(PADDING)
.help( .help(get_message("numfmt-help-padding"))
"pad the output to N characters; positive N will \
right-align; negative N will left-align; padding is \
ignored if the output is wider than N; the default is \
to automatically pad if a whitespace is found",
)
.value_name("N"), .value_name("N"),
) )
.arg( .arg(
Arg::new(HEADER) Arg::new(HEADER)
.long(HEADER) .long(HEADER)
.help( .help(get_message("numfmt-help-header"))
"print (without converting) the first N header lines; \
N defaults to 1 if not specified",
)
.num_args(..=1) .num_args(..=1)
.value_name("N") .value_name("N")
.default_missing_value(HEADER_DEFAULT) .default_missing_value(HEADER_DEFAULT)
@ -355,7 +365,7 @@ pub fn uu_app() -> Command {
.arg( .arg(
Arg::new(ROUND) Arg::new(ROUND)
.long(ROUND) .long(ROUND)
.help("use METHOD for rounding when scaling") .help(get_message("numfmt-help-round"))
.value_name("METHOD") .value_name("METHOD")
.default_value("from-zero") .default_value("from-zero")
.value_parser(ShortcutValueParser::new([ .value_parser(ShortcutValueParser::new([
@ -369,16 +379,13 @@ pub fn uu_app() -> Command {
.arg( .arg(
Arg::new(SUFFIX) Arg::new(SUFFIX)
.long(SUFFIX) .long(SUFFIX)
.help( .help(get_message("numfmt-help-suffix"))
"print SUFFIX after each formatted number, and accept \
inputs optionally ending with SUFFIX",
)
.value_name("SUFFIX"), .value_name("SUFFIX"),
) )
.arg( .arg(
Arg::new(INVALID) Arg::new(INVALID)
.long(INVALID) .long(INVALID)
.help("set the failure mode for invalid input") .help(get_message("numfmt-help-invalid"))
.default_value("abort") .default_value("abort")
.value_parser(["abort", "fail", "warn", "ignore"]) .value_parser(["abort", "fail", "warn", "ignore"])
.value_name("INVALID"), .value_name("INVALID"),
@ -387,7 +394,7 @@ pub fn uu_app() -> Command {
Arg::new(ZERO_TERMINATED) Arg::new(ZERO_TERMINATED)
.long(ZERO_TERMINATED) .long(ZERO_TERMINATED)
.short('z') .short('z')
.help("line delimiter is NUL, not newline") .help(get_message("numfmt-help-zero-terminated"))
.action(ArgAction::SetTrue), .action(ArgAction::SetTrue),
) )
.arg(Arg::new(NUMBER).hide(true).action(ArgAction::Append)) .arg(Arg::new(NUMBER).hide(true).action(ArgAction::Append))
@ -465,9 +472,9 @@ mod tests {
let result_display = format!("{result}"); let result_display = format!("{result}");
assert_eq!( assert_eq!(
result_debug, result_debug,
"FormattingError(\"invalid suffix in input: 'hello'\")" "FormattingError(\"numfmt-error-invalid-suffix\")"
); );
assert_eq!(result_display, "invalid suffix in input: 'hello'"); assert_eq!(result_display, "numfmt-error-invalid-suffix");
assert_eq!(result.code(), 2); assert_eq!(result.code(), 2);
} }

View file

@ -2,9 +2,11 @@
// //
// For the full copyright and license information, please view the LICENSE // For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code. // file that was distributed with this source code.
use std::collections::HashMap;
use std::str::FromStr; use std::str::FromStr;
use crate::units::Unit; use crate::units::Unit;
use uucore::locale::get_message_with_args;
use uucore::ranges::Range; use uucore::ranges::Range;
pub const DELIMITER: &str = "delimiter"; pub const DELIMITER: &str = "delimiter";
@ -145,9 +147,15 @@ impl FromStr for FormatOptions {
if iter.peek().is_none() { if iter.peek().is_none() {
return if options.prefix == s { return if options.prefix == s {
Err(format!("format '{s}' has no % directive")) Err(get_message_with_args(
"numfmt-error-format-no-percent",
HashMap::from([("format".to_string(), s.to_string())]),
))
} else { } else {
Err(format!("format '{s}' ends in %")) Err(get_message_with_args(
"numfmt-error-format-ends-in-percent",
HashMap::from([("format".to_string(), s.to_string())]),
))
}; };
} }
@ -167,8 +175,9 @@ impl FromStr for FormatOptions {
match iter.peek() { match iter.peek() {
Some(c) if c.is_ascii_digit() => padding.push('-'), Some(c) if c.is_ascii_digit() => padding.push('-'),
_ => { _ => {
return Err(format!( return Err(get_message_with_args(
"invalid format '{s}', directive must be %[0]['][-][N][.][N]f" "numfmt-error-invalid-format-directive",
HashMap::from([("format".to_string(), s.to_string())]),
)); ));
} }
} }
@ -187,7 +196,10 @@ impl FromStr for FormatOptions {
if let Ok(p) = padding.parse() { if let Ok(p) = padding.parse() {
options.padding = Some(p); options.padding = Some(p);
} else { } else {
return Err(format!("invalid format '{s}' (width overflow)")); return Err(get_message_with_args(
"numfmt-error-invalid-format-width-overflow",
HashMap::from([("format".to_string(), s.to_string())]),
));
} }
} }
@ -195,7 +207,10 @@ impl FromStr for FormatOptions {
iter.next(); iter.next();
if matches!(iter.peek(), Some(' ' | '+' | '-')) { if matches!(iter.peek(), Some(' ' | '+' | '-')) {
return Err(format!("invalid precision in format '{s}'")); return Err(get_message_with_args(
"numfmt-error-invalid-precision",
HashMap::from([("format".to_string(), s.to_string())]),
));
} }
while let Some(c) = iter.peek() { while let Some(c) = iter.peek() {
@ -212,15 +227,19 @@ impl FromStr for FormatOptions {
} else if let Ok(p) = precision.parse() { } else if let Ok(p) = precision.parse() {
options.precision = Some(p); options.precision = Some(p);
} else { } else {
return Err(format!("invalid precision in format '{s}'")); return Err(get_message_with_args(
"numfmt-error-invalid-precision",
HashMap::from([("format".to_string(), s.to_string())]),
));
} }
} }
if let Some('f') = iter.peek() { if let Some('f') = iter.peek() {
iter.next(); iter.next();
} else { } else {
return Err(format!( return Err(get_message_with_args(
"invalid format '{s}', directive must be %[0]['][-][N][.][N]f" "numfmt-error-invalid-format-directive",
HashMap::from([("format".to_string(), s.to_string())]),
)); ));
} }
@ -235,7 +254,10 @@ impl FromStr for FormatOptions {
} }
iter.next(); iter.next();
} else { } else {
return Err(format!("format '{s}' has too many % directives")); return Err(get_message_with_args(
"numfmt-error-format-too-many-percent",
HashMap::from([("format".to_string(), s.to_string())]),
));
} }
} }
@ -252,7 +274,10 @@ impl FromStr for InvalidModes {
"fail" => Ok(Self::Fail), "fail" => Ok(Self::Fail),
"warn" => Ok(Self::Warn), "warn" => Ok(Self::Warn),
"ignore" => Ok(Self::Ignore), "ignore" => Ok(Self::Ignore),
unknown => Err(format!("Unknown invalid mode: {unknown}")), unknown => Err(get_message_with_args(
"numfmt-error-unknown-invalid-mode",
HashMap::from([("mode".to_string(), unknown.to_string())]),
)),
} }
} }
} }