Skip to main content

reifydb_codec/primitive/
decimal.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_value::{
5	reifydb_assertions,
6	value::{decimal::Decimal, value_type::ValueType},
7};
8
9use crate::{
10	row::{bytes::RowBuilder, shape::RowShape},
11	unscaled::{decimal_unscaled, read_le, write_le},
12};
13
14impl RowShape {
15	pub fn set_decimal(&self, row: &mut impl RowBuilder, index: usize, value: &Decimal) {
16		let field = &self.fields()[index];
17		reifydb_assertions! {
18			assert!(
19				row.len() >= self.total_static_size(),
20				"row/shape size mismatch: row.len()={} < total_static_size()={}",
21				row.len(),
22				self.total_static_size()
23			);
24		}
25		let ValueType::Decimal {
26			precision,
27			scale,
28		} = *field.constraint.get_type().inner_type()
29		else {
30			panic!("set_decimal on field {:?} of type {}", field.name, field.constraint.get_type());
31		};
32		let unscaled = decimal_unscaled(value, precision, scale).unwrap_or_else(|| {
33			panic!(
34				"decimal {value} does not fit field {:?} of type {}",
35				field.name,
36				field.constraint.get_type()
37			)
38		});
39		let start = field.offset as usize;
40		write_le(unscaled, &mut row.as_mut_slice()[start..start + field.size as usize]);
41		self.set_valid(row, index, true);
42	}
43
44	pub fn get_decimal(&self, row: &[u8], index: usize) -> Decimal {
45		let field = &self.fields()[index];
46		reifydb_assertions! {
47			assert!(
48				row.len() >= self.total_static_size(),
49				"row/shape size mismatch: row.len()={} < total_static_size()={}",
50				row.len(),
51				self.total_static_size()
52			);
53		}
54		let ValueType::Decimal {
55			scale,
56			..
57		} = *field.constraint.get_type().inner_type()
58		else {
59			panic!("get_decimal on field {:?} of type {}", field.name, field.constraint.get_type());
60		};
61		let start = field.offset as usize;
62		let unscaled = read_le(&row[start..start + field.size as usize]);
63		Decimal::from_parts(unscaled, scale.value()).expect("a stored decimal is within 76 digits")
64	}
65}