alamb commented on code in PR #11002:
URL: https://github.com/apache/arrow-rs/pull/11002#discussion_r4039823971
##########
arrow-array/src/types.rs:
##########
@@ -1418,8 +1418,12 @@ pub trait DecimalType:
/// "Decimal32", "Decimal64", "Decimal128" or "Decimal256", for use in
error messages
const PREFIX: &'static str;
- /// Formats the decimal value with the provided precision and scale
- fn format_decimal(value: Self::Native, precision: u8, scale: i8) -> String;
+ /// Formats `value` with `scale` fractional digits. The value is always
Review Comment:
Maybe we can just add a doc example somewhere on how to do it if it doesn't
exist. I don't think we need a new wrapper necessairly
##########
arrow-data/src/decimal.rs:
##########
@@ -1126,37 +1103,149 @@ pub fn format_decimal_str(value_str: &str, _precision:
usize, scale: i8) -> Stri
format_decimal_str_internal(value_str, scale)
}
-// Format a decimal string given the scale.
+/// The native value of a decimal type: `i32`, `i64`, `i128` or `i256`
+pub trait DecimalNativeType: Display + sealed::DecimalNativeTypeSealed {}
+
+mod sealed {
+ pub trait DecimalNativeTypeSealed {}
+}
+
+macro_rules! decimal_native {
+ ($($t:ty),+) => {
+ $(
+ impl sealed::DecimalNativeTypeSealed for $t {}
+ impl DecimalNativeType for $t {}
+ )+
+ };
+}
+
+decimal_native!(i32, i64, i128, i256);
+
+/// Formats the unscaled decimal `value` with `scale` fractional digits: the
+/// decimal point is inserted `scale` digits from the right, with leading
+/// zeros as needed, and a negative scale appends zeros instead. The value is
+/// always formatted in full, whatever its precision.
+pub fn format_decimal<V: DecimalNativeType>(value: V, scale: i8) -> String {
+ format_decimal_str_internal(DigitBuffer::from_value(&value).as_str(),
scale)
+}
+
+/// Like [`format_decimal`], but writes the result to `f` instead of returning
+/// a new `String`.
+pub fn write_decimal<V: DecimalNativeType>(
+ f: &mut dyn Write,
+ value: V,
+ scale: i8,
+) -> std::fmt::Result {
+ write_decimal_str(f, DigitBuffer::from_value(&value).as_str(), scale)
+}
+
+/// Formats `value_str` as [`write_decimal_str`] does, into a `String` with
+/// enough capacity to avoid reallocation
fn format_decimal_str_internal(value_str: &str, scale: i8) -> String {
- let (sign, rest) = match value_str.strip_prefix('-') {
- Some(stripped) => ("-", stripped),
+ let mut out = String::with_capacity(value_str.len() + scale.unsigned_abs()
as usize + 2);
+ write_decimal_str(&mut out, value_str, scale).expect("writing to a String
cannot fail");
+ out
+}
+
+/// The length of the longest decimal native value when formatted: `i256::MIN`
+/// has 77 digits and a sign
+const MAX_DECIMAL_VALUE_LEN: usize = 78;
+
+/// The formatted digits of a decimal native value, with its sign
Review Comment:
(see above, this already exists)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]