@@ -23,6 +23,7 @@ use serde_json::Value;
2323use std:: io:: Write ;
2424
2525use crate :: variant:: { Variant , VariantList , VariantObject } ;
26+ use crate :: { VariantDecimal16 , VariantDecimal4 , VariantDecimal8 } ;
2627
2728// Format string constants to avoid duplication and reduce errors
2829const DATE_FORMAT : & str = "%Y-%m-%d" ;
@@ -106,7 +107,7 @@ pub fn variant_to_json(json_buffer: &mut impl Write, variant: &Variant) -> Resul
106107 Variant :: Double ( f) => {
107108 write ! ( json_buffer, "{}" , f) ?;
108109 }
109- Variant :: Decimal4 { integer, scale } => {
110+ Variant :: Decimal4 ( VariantDecimal4 { integer, scale } ) => {
110111 // Convert decimal to string representation using integer arithmetic
111112 if * scale == 0 {
112113 write ! ( json_buffer, "{}" , integer) ?;
@@ -123,7 +124,7 @@ pub fn variant_to_json(json_buffer: &mut impl Write, variant: &Variant) -> Resul
123124 }
124125 }
125126 }
126- Variant :: Decimal8 { integer, scale } => {
127+ Variant :: Decimal8 ( VariantDecimal8 { integer, scale } ) => {
127128 // Convert decimal to string representation using integer arithmetic
128129 if * scale == 0 {
129130 write ! ( json_buffer, "{}" , integer) ?;
@@ -140,7 +141,7 @@ pub fn variant_to_json(json_buffer: &mut impl Write, variant: &Variant) -> Resul
140141 }
141142 }
142143 }
143- Variant :: Decimal16 { integer, scale } => {
144+ Variant :: Decimal16 ( VariantDecimal16 { integer, scale } ) => {
144145 // Convert decimal to string representation using integer arithmetic
145146 if * scale == 0 {
146147 write ! ( json_buffer, "{}" , integer) ?;
@@ -364,7 +365,7 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
364365 Variant :: Double ( f) => serde_json:: Number :: from_f64 ( * f)
365366 . map ( Value :: Number )
366367 . ok_or_else ( || ArrowError :: InvalidArgumentError ( "Invalid double value" . to_string ( ) ) ) ,
367- Variant :: Decimal4 { integer, scale } => {
368+ Variant :: Decimal4 ( VariantDecimal4 { integer, scale } ) => {
368369 // Use integer arithmetic to avoid f64 precision loss
369370 if * scale == 0 {
370371 Ok ( Value :: Number ( ( * integer) . into ( ) ) )
@@ -390,7 +391,7 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
390391 } )
391392 }
392393 }
393- Variant :: Decimal8 { integer, scale } => {
394+ Variant :: Decimal8 ( VariantDecimal8 { integer, scale } ) => {
394395 // Use integer arithmetic to avoid f64 precision loss
395396 if * scale == 0 {
396397 Ok ( Value :: Number ( ( * integer) . into ( ) ) )
@@ -416,7 +417,7 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> {
416417 } )
417418 }
418419 }
419- Variant :: Decimal16 { integer, scale } => {
420+ Variant :: Decimal16 ( VariantDecimal16 { integer, scale } ) => {
420421 // Use integer arithmetic to avoid f64 precision loss
421422 if * scale == 0 {
422423 Ok ( Value :: Number ( ( * integer as i64 ) . into ( ) ) ) // Convert to i64 for JSON compatibility
@@ -482,18 +483,12 @@ mod tests {
482483 #[ test]
483484 fn test_decimal_edge_cases ( ) -> Result < ( ) , ArrowError > {
484485 // Test negative decimal
485- let negative_variant = Variant :: Decimal4 {
486- integer : -12345 ,
487- scale : 3 ,
488- } ;
486+ let negative_variant = Variant :: from ( VariantDecimal4 :: try_new ( -12345 , 3 ) ?) ;
489487 let negative_json = variant_to_json_string ( & negative_variant) ?;
490488 assert_eq ! ( negative_json, "-12.345" ) ;
491489
492490 // Test large scale decimal
493- let large_scale_variant = Variant :: Decimal8 {
494- integer : 123456789 ,
495- scale : 6 ,
496- } ;
491+ let large_scale_variant = Variant :: from ( VariantDecimal8 :: try_new ( 123456789 , 6 ) ?) ;
497492 let large_scale_json = variant_to_json_string ( & large_scale_variant) ?;
498493 assert_eq ! ( large_scale_json, "123.456789" ) ;
499494
@@ -502,21 +497,15 @@ mod tests {
502497
503498 #[ test]
504499 fn test_decimal16_to_json ( ) -> Result < ( ) , ArrowError > {
505- let variant = Variant :: Decimal16 {
506- integer : 123456789012345 ,
507- scale : 4 ,
508- } ;
500+ let variant = Variant :: from ( VariantDecimal16 :: try_new ( 123456789012345 , 4 ) ?) ;
509501 let json = variant_to_json_string ( & variant) ?;
510502 assert_eq ! ( json, "12345678901.2345" ) ;
511503
512504 let json_value = variant_to_json_value ( & variant) ?;
513505 assert ! ( matches!( json_value, Value :: Number ( _) ) ) ;
514506
515507 // Test very large number
516- let large_variant = Variant :: Decimal16 {
517- integer : 999999999999999999 ,
518- scale : 2 ,
519- } ;
508+ let large_variant = Variant :: from ( VariantDecimal16 :: try_new ( 999999999999999999 , 2 ) ?) ;
520509 let large_json = variant_to_json_string ( & large_variant) ?;
521510 // Due to f64 precision limits, very large numbers may lose precision
522511 assert ! (
@@ -839,10 +828,7 @@ mod tests {
839828
840829 // Decimals
841830 JsonTest {
842- variant : Variant :: Decimal4 {
843- integer : 12345 ,
844- scale : 2 ,
845- } ,
831+ variant : Variant :: from ( VariantDecimal4 :: try_new ( 12345 , 2 ) . unwrap ( ) ) ,
846832 expected_json : "123.45" ,
847833 expected_value : serde_json:: Number :: from_f64 ( 123.45 )
848834 . map ( Value :: Number )
@@ -851,10 +837,7 @@ mod tests {
851837 . run ( ) ;
852838
853839 JsonTest {
854- variant : Variant :: Decimal4 {
855- integer : 42 ,
856- scale : 0 ,
857- } ,
840+ variant : Variant :: from ( VariantDecimal4 :: try_new ( 42 , 0 ) . unwrap ( ) ) ,
858841 expected_json : "42" ,
859842 expected_value : serde_json:: Number :: from_f64 ( 42.0 )
860843 . map ( Value :: Number )
@@ -863,10 +846,7 @@ mod tests {
863846 . run ( ) ;
864847
865848 JsonTest {
866- variant : Variant :: Decimal8 {
867- integer : 1234567890 ,
868- scale : 3 ,
869- } ,
849+ variant : Variant :: from ( VariantDecimal8 :: try_new ( 1234567890 , 3 ) . unwrap ( ) ) ,
870850 expected_json : "1234567.89" ,
871851 expected_value : serde_json:: Number :: from_f64 ( 1234567.89 )
872852 . map ( Value :: Number )
@@ -875,10 +855,7 @@ mod tests {
875855 . run ( ) ;
876856
877857 JsonTest {
878- variant : Variant :: Decimal16 {
879- integer : 123456789012345 ,
880- scale : 4 ,
881- } ,
858+ variant : Variant :: from ( VariantDecimal16 :: try_new ( 123456789012345 , 4 ) . unwrap ( ) ) ,
882859 expected_json : "12345678901.2345" ,
883860 expected_value : serde_json:: Number :: from_f64 ( 12345678901.2345 )
884861 . map ( Value :: Number )
@@ -1277,10 +1254,10 @@ mod tests {
12771254 fn test_high_precision_decimal_no_loss ( ) -> Result < ( ) , ArrowError > {
12781255 // Test case that would lose precision with f64 conversion
12791256 // This is a 63-bit precision decimal8 value that f64 cannot represent exactly
1280- let high_precision_decimal8 = Variant :: Decimal8 {
1281- integer : 9007199254740993 , // 2^53 + 1, exceeds f64 precision
1282- scale : 6 ,
1283- } ;
1257+ let high_precision_decimal8 = Variant :: from ( VariantDecimal8 :: try_new (
1258+ 9007199254740993 , // 2^53 + 1, exceeds f64 precision
1259+ 6 ,
1260+ ) ? ) ;
12841261
12851262 let json_string = variant_to_json_string ( & high_precision_decimal8) ?;
12861263 let json_value = variant_to_json_value ( & high_precision_decimal8) ?;
@@ -1294,10 +1271,10 @@ mod tests {
12941271 assert_eq ! ( parsed, json_value) ;
12951272
12961273 // Test another case with trailing zeros that should be trimmed
1297- let decimal_with_zeros = Variant :: Decimal8 {
1298- integer : 1234567890000 , // Should result in 1234567.89 (trailing zeros trimmed)
1299- scale : 6 ,
1300- } ;
1274+ let decimal_with_zeros = Variant :: from ( VariantDecimal8 :: try_new (
1275+ 1234567890000 , // Should result in 1234567.89 (trailing zeros trimmed)
1276+ 6 ,
1277+ ) ? ) ;
13011278
13021279 let json_string_zeros = variant_to_json_string ( & decimal_with_zeros) ?;
13031280 assert_eq ! ( json_string_zeros, "1234567.89" ) ;
0 commit comments