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