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 {precision} exceeds MAX_PRECISION"
43 );
44
45 assert!(
46 scale <= MAX_SCALE,
47 "decimal scale {scale} exceeds MAX_SCALE"
48 );
49
50 Self { precision, scale }
51 }
52
53 pub fn precision(&self) -> u8 {
55 self.precision
56 }
57
58 pub fn scale(&self) -> i8 {
63 self.scale
64 }
65
66 pub fn required_bit_width(&self) -> usize {
68 (self.precision as f32 * 10.0f32.log(2.0))
69 .ceil()
70 .to_usize()
71 .vortex_expect("too many bits required")
72 }
73}
74
75impl Display for DecimalDType {
76 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
77 write!(f, "decimal({},{})", self.precision, self.scale)
78 }
79}
80
81impl TryFrom<&DType> for DecimalDType {
82 type Error = VortexError;
83
84 fn try_from(value: &DType) -> Result<Self, Self::Error> {
85 match value {
86 DType::Decimal(dt, _) => Ok(*dt),
87 _ => vortex_bail!("Cannot convert DType {value} into DecimalType"),
88 }
89 }
90}
91
92impl TryFrom<DType> for DecimalDType {
93 type Error = VortexError;
94
95 fn try_from(value: DType) -> Result<Self, Self::Error> {
96 Self::try_from(&value)
97 }
98}