vortex_dtype/
decimal.rs

1use vortex_error::{VortexError, vortex_err};
2
3use crate::DType;
4
5const MAX_PRECISION: u8 = 76;
6const MAX_SCALE: i8 = 76;
7
8/// Maximum precision for a Decimal128 type from Arrow
9pub const DECIMAL128_MAX_PRECISION: u8 = 38;
10
11/// Parameters that define the precision and scale of a decimal type.
12///
13/// Decimal types allow real numbers with a similar precision and scale to be represented exactly.
14#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct DecimalDType {
17    precision: u8,
18    scale: i8,
19}
20
21impl DecimalDType {
22    /// Checked constructor for a `DecimalDType`.
23    ///
24    /// # Panics
25    ///
26    /// Attempting to build a new instance with invalid precision or scale values will panic.
27    pub fn new(precision: u8, scale: i8) -> Self {
28        assert!(
29            precision <= MAX_PRECISION,
30            "decimal precision {} exceeds MAX_PRECISION",
31            precision
32        );
33
34        assert!(
35            scale <= MAX_SCALE,
36            "decimal scale {} exceeds MAX_SCALE",
37            scale
38        );
39
40        Self { precision, scale }
41    }
42
43    /// The precision is the number of significant figures that the decimal tracks.
44    pub fn precision(&self) -> u8 {
45        self.precision
46    }
47
48    /// The scale is the maximum number of digits relative to the decimal point.
49    ///
50    /// Positive scale means digits after decimal point, negative scale means number of
51    /// zeros before the decimal point.
52    pub fn scale(&self) -> i8 {
53        self.scale
54    }
55}
56
57impl TryFrom<&DType> for DecimalDType {
58    type Error = VortexError;
59
60    fn try_from(value: &DType) -> Result<Self, Self::Error> {
61        match value {
62            DType::Decimal(dt, _) => Ok(*dt),
63            _ => Err(vortex_err!(
64                "Cannot convert DType {} into DecimalType",
65                value
66            )),
67        }
68    }
69}
70
71impl TryFrom<DType> for DecimalDType {
72    type Error = VortexError;
73
74    fn try_from(value: DType) -> Result<Self, Self::Error> {
75        Self::try_from(&value)
76    }
77}