Skip to main content

reifydb_codec/
constraint.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_value::value::{
5	constraint::{Constraint, TypeConstraint, bytes::MaxBytes, precision::Precision, scale::Scale},
6	dictionary::DictionaryId,
7	sumtype::SumTypeId,
8};
9
10use crate::{
11	error::{DecodeError, EncodeError},
12	tag::TypeTag,
13};
14
15#[repr(C)]
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub struct EncodedTypeConstraint {
18	pub base_type: u8,
19
20	pub constraint_type: u8,
21
22	pub constraint_param1: u32,
23
24	pub constraint_param2: u32,
25}
26
27pub fn encode_type_constraint(tc: &TypeConstraint) -> Result<EncodedTypeConstraint, EncodeError> {
28	let base_type = TypeTag::of_type(&tc.get_type())?.byte();
29	Ok(match tc.constraint() {
30		None => EncodedTypeConstraint {
31			base_type,
32			constraint_type: 0,
33			constraint_param1: 0,
34			constraint_param2: 0,
35		},
36		Some(Constraint::MaxBytes(max)) => EncodedTypeConstraint {
37			base_type,
38			constraint_type: 1,
39			constraint_param1: max.value(),
40			constraint_param2: 0,
41		},
42		Some(Constraint::PrecisionScale(p, s)) => EncodedTypeConstraint {
43			base_type,
44			constraint_type: 2,
45			constraint_param1: p.value() as u32,
46			constraint_param2: s.value() as u32,
47		},
48		Some(Constraint::Dictionary(dict_id, id_type)) => EncodedTypeConstraint {
49			base_type,
50			constraint_type: 3,
51			constraint_param1: dict_id.to_u64() as u32,
52			constraint_param2: TypeTag::of_type(id_type)?.byte() as u32,
53		},
54		Some(Constraint::SumType(id)) => EncodedTypeConstraint {
55			base_type,
56			constraint_type: 4,
57			constraint_param1: id.to_u64() as u32,
58			constraint_param2: 0,
59		},
60	})
61}
62
63pub fn decode_type_constraint(encoded: &EncodedTypeConstraint) -> Result<TypeConstraint, DecodeError> {
64	let ty = TypeTag::from_byte(encoded.base_type)?.to_type()?;
65	Ok(match encoded.constraint_type {
66		1 => TypeConstraint::with_constraint(
67			ty,
68			Constraint::MaxBytes(MaxBytes::new(encoded.constraint_param1)),
69		),
70		2 => TypeConstraint::with_constraint(
71			ty,
72			Constraint::PrecisionScale(
73				Precision::new(encoded.constraint_param1 as u8),
74				Scale::new(encoded.constraint_param2 as u8),
75			),
76		),
77		3 => TypeConstraint::with_constraint(
78			ty,
79			Constraint::Dictionary(
80				DictionaryId::from(encoded.constraint_param1 as u64),
81				TypeTag::from_byte(encoded.constraint_param2 as u8)?.to_type()?,
82			),
83		),
84		4 => TypeConstraint::with_constraint(
85			ty,
86			Constraint::SumType(SumTypeId::from(encoded.constraint_param1 as u64)),
87		),
88		_ => TypeConstraint::unconstrained(ty),
89	})
90}