1use std::fmt::{Display, Formatter};
5
6use num_traits::ToPrimitive;
7use vortex_error::{VortexError, VortexExpect, vortex_bail};
8
9use crate::DType;
10
11const MAX_PRECISION: u8 = 76;
12const MAX_SCALE: i8 = 76;
13
14pub const DECIMAL128_MAX_PRECISION: u8 = 38;
16
17pub const DECIMAL256_MAX_PRECISION: u8 = 76;
19
20pub const DECIMAL128_MAX_SCALE: i8 = 38;
22
23pub const DECIMAL256_MAX_SCALE: i8 = 76;
25
26#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub struct DecimalDType {
32 precision: u8,
33 scale: i8,
34}
35
36impl DecimalDType {
37 pub fn new(precision: u8, scale: i8) -> Self {
43 assert!(
44 precision <= MAX_PRECISION,
45 "decimal precision {precision} exceeds MAX_PRECISION"
46 );
47
48 assert!(
49 scale <= MAX_SCALE,
50 "decimal scale {scale} exceeds MAX_SCALE"
51 );
52
53 Self { precision, scale }
54 }
55
56 pub fn precision(&self) -> u8 {
58 self.precision
59 }
60
61 pub fn scale(&self) -> i8 {
66 self.scale
67 }
68
69 pub fn required_bit_width(&self) -> usize {
71 (self.precision as f32 * 10.0f32.log(2.0))
72 .ceil()
73 .to_usize()
74 .vortex_expect("too many bits required")
75 }
76}
77
78impl Display for DecimalDType {
79 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
80 write!(f, "decimal({},{})", self.precision, self.scale)
81 }
82}
83
84impl TryFrom<&DType> for DecimalDType {
85 type Error = VortexError;
86
87 fn try_from(value: &DType) -> Result<Self, Self::Error> {
88 match value {
89 DType::Decimal(dt, _) => Ok(*dt),
90 _ => vortex_bail!("Cannot convert DType {value} into DecimalType"),
91 }
92 }
93}
94
95impl TryFrom<DType> for DecimalDType {
96 type Error = VortexError;
97
98 fn try_from(value: DType) -> Result<Self, Self::Error> {
99 Self::try_from(&value)
100 }
101}