Skip to main content

reifydb_core/key/
procedure.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use reifydb_codec::key::{deserializer::KeyDeserializer, encoded::EncodedKey, serializer::KeySerializer};
5use smallvec::{SmallVec, smallvec};
6
7use super::KeyTag;
8use crate::{
9	interface::catalog::id::ProcedureId,
10	key::{
11		any::{Field, KeyFields, Width},
12		bound::TaggedKeyBoundRange,
13	},
14};
15
16#[derive(Debug, Clone, PartialEq, Hash)]
17pub struct ProcedureKey {
18	pub procedure: ProcedureId,
19}
20
21impl ProcedureKey {
22	pub const TAG: KeyTag = KeyTag::Procedure;
23
24	pub fn encode(&self) -> EncodedKey {
25		let mut serializer = KeySerializer::with_capacity(9);
26		serializer.extend_u8(Self::TAG as u8).extend_u64(self.procedure);
27		serializer.to_encoded_key()
28	}
29
30	pub fn decode(key: &EncodedKey) -> Option<Self> {
31		let mut de = KeyDeserializer::from_bytes(key.as_slice());
32
33		let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
34		if kind != Self::TAG {
35			return None;
36		}
37
38		let procedure = de.read_u64().ok()?;
39
40		Some(Self {
41			procedure: ProcedureId::from_raw(procedure),
42		})
43	}
44}
45
46impl ProcedureKey {
47	pub fn new(procedure: impl Into<ProcedureId>) -> Self {
48		Self {
49			procedure: procedure.into(),
50		}
51	}
52
53	pub fn encoded(procedure: impl Into<ProcedureId>) -> EncodedKey {
54		Self::new(procedure).encode()
55	}
56
57	pub fn full_scan() -> TaggedKeyBoundRange {
58		TaggedKeyBoundRange::kind(Self::TAG)
59	}
60}
61
62#[cfg(test)]
63pub mod procedure_key_tests {
64	use super::ProcedureKey;
65	use crate::interface::catalog::id::ProcedureId;
66
67	#[test]
68	fn test_encode_decode() {
69		let key = ProcedureKey {
70			procedure: ProcedureId::from_raw(0xABCD),
71		};
72		let encoded = key.encode();
73		let key = ProcedureKey::decode(&encoded).unwrap();
74		assert_eq!(key.procedure, 0xABCD);
75	}
76}
77
78#[derive(Debug, Clone, PartialEq, Hash)]
79pub struct ProcedureParamKey {
80	pub procedure: ProcedureId,
81	pub param_index: u16,
82}
83
84impl ProcedureParamKey {
85	pub const TAG: KeyTag = KeyTag::ProcedureParam;
86
87	pub fn encode(&self) -> EncodedKey {
88		let mut serializer = KeySerializer::with_capacity(11);
89		serializer.extend_u8(Self::TAG as u8).extend_u64(self.procedure).extend_u16(self.param_index);
90		serializer.to_encoded_key()
91	}
92
93	pub fn decode(key: &EncodedKey) -> Option<Self> {
94		let mut de = KeyDeserializer::from_bytes(key.as_slice());
95
96		let kind: KeyTag = de.read_u8().ok()?.try_into().ok()?;
97		if kind != Self::TAG {
98			return None;
99		}
100
101		let procedure = de.read_u64().ok()?;
102		let param_index = de.read_u16().ok()?;
103
104		Some(Self {
105			procedure: ProcedureId::from_raw(procedure),
106			param_index,
107		})
108	}
109}
110
111impl ProcedureParamKey {
112	pub fn new(procedure: impl Into<ProcedureId>, param_index: u16) -> Self {
113		Self {
114			procedure: procedure.into(),
115			param_index,
116		}
117	}
118
119	pub fn encoded(procedure: impl Into<ProcedureId>, param_index: u16) -> EncodedKey {
120		Self::new(procedure, param_index).encode()
121	}
122
123	pub fn full_scan(procedure: ProcedureId) -> TaggedKeyBoundRange {
124		TaggedKeyBoundRange::prefix(Self::TAG, [Field::UDesc(Width::U64, *procedure as u128)])
125	}
126}
127
128#[cfg(test)]
129pub mod procedure_param_key_tests {
130	use super::ProcedureParamKey;
131	use crate::interface::catalog::id::ProcedureId;
132
133	#[test]
134	fn test_encode_decode() {
135		let key = ProcedureParamKey {
136			procedure: ProcedureId::from_raw(0xCAFE),
137			param_index: 7,
138		};
139		let encoded = key.encode();
140		let key = ProcedureParamKey::decode(&encoded).unwrap();
141		assert_eq!(key.procedure, 0xCAFE);
142		assert_eq!(key.param_index, 7);
143	}
144}
145
146impl KeyFields for ProcedureKey {
147	fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
148		smallvec![Field::UDesc(Width::U64, *self.procedure as u128)]
149	}
150}
151
152impl KeyFields for ProcedureParamKey {
153	fn fields(&self) -> SmallVec<[Field<'_>; 6]> {
154		smallvec![
155			Field::UDesc(Width::U64, *self.procedure as u128),
156			Field::UDesc(Width::U16, self.param_index as u128)
157		]
158	}
159}