arrow_json/reader/
decimal_array.rs1use std::marker::PhantomData;
19
20use arrow_array::builder::PrimitiveBuilder;
21use arrow_array::types::DecimalType;
22use arrow_array::Array;
23use arrow_cast::parse::parse_decimal;
24use arrow_data::ArrayData;
25use arrow_schema::ArrowError;
26
27use crate::reader::tape::{Tape, TapeElement};
28use crate::reader::ArrayDecoder;
29
30pub struct DecimalArrayDecoder<D: DecimalType> {
31 precision: u8,
32 scale: i8,
33 phantom: PhantomData<fn(D) -> D>,
35}
36
37impl<D: DecimalType> DecimalArrayDecoder<D> {
38 pub fn new(precision: u8, scale: i8) -> Self {
39 Self {
40 precision,
41 scale,
42 phantom: PhantomData,
43 }
44 }
45}
46
47impl<D> ArrayDecoder for DecimalArrayDecoder<D>
48where
49 D: DecimalType,
50{
51 fn decode(&mut self, tape: &Tape<'_>, pos: &[u32]) -> Result<ArrayData, ArrowError> {
52 let mut builder = PrimitiveBuilder::<D>::with_capacity(pos.len());
53
54 for p in pos {
55 match tape.get(*p) {
56 TapeElement::Null => builder.append_null(),
57 TapeElement::String(idx) => {
58 let s = tape.get_string(idx);
59 let value = parse_decimal::<D>(s, self.precision, self.scale)?;
60 builder.append_value(value)
61 }
62 TapeElement::Number(idx) => {
63 let s = tape.get_string(idx);
64 let value = parse_decimal::<D>(s, self.precision, self.scale)?;
65 builder.append_value(value)
66 }
67 TapeElement::I64(high) => match tape.get(*p + 1) {
68 TapeElement::I32(low) => {
69 let val = (((high as i64) << 32) | (low as u32) as i64).to_string();
70 let value = parse_decimal::<D>(&val, self.precision, self.scale)?;
71 builder.append_value(value)
72 }
73 _ => unreachable!(),
74 },
75 TapeElement::I32(val) => {
76 let s = val.to_string();
77 let value = parse_decimal::<D>(&s, self.precision, self.scale)?;
78 builder.append_value(value)
79 }
80 TapeElement::F64(high) => match tape.get(*p + 1) {
81 TapeElement::F32(low) => {
82 let val = f64::from_bits(((high as u64) << 32) | low as u64).to_string();
83 let value = parse_decimal::<D>(&val, self.precision, self.scale)?;
84 builder.append_value(value)
85 }
86 _ => unreachable!(),
87 },
88 TapeElement::F32(val) => {
89 let s = f32::from_bits(val).to_string();
90 let value = parse_decimal::<D>(&s, self.precision, self.scale)?;
91 builder.append_value(value)
92 }
93 _ => return Err(tape.error(*p, "decimal")),
94 }
95 }
96
97 Ok(builder
98 .finish()
99 .with_precision_and_scale(self.precision, self.scale)?
100 .into_data())
101 }
102}