1use reifydb_type::value::sumtype::SumTypeId;
5
6use crate::{
7 encoded::key::{EncodedKey, EncodedKeyRange},
8 interface::catalog::id::{HandlerId, NamespaceId},
9 key::{EncodableKey, KeyKind},
10 util::encoding::keycode::{deserializer::KeyDeserializer, serializer::KeySerializer},
11};
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct VariantHandlerKey {
15 pub namespace: NamespaceId,
16 pub sumtype: SumTypeId,
17 pub variant_tag: u8,
18 pub handler: HandlerId,
19}
20
21impl VariantHandlerKey {
22 pub fn new(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8, handler: HandlerId) -> Self {
23 Self {
24 namespace,
25 sumtype,
26 variant_tag,
27 handler,
28 }
29 }
30
31 pub fn encoded(
32 namespace: impl Into<NamespaceId>,
33 sumtype: impl Into<SumTypeId>,
34 variant_tag: u8,
35 handler: impl Into<HandlerId>,
36 ) -> EncodedKey {
37 Self::new(namespace.into(), sumtype.into(), variant_tag, handler.into()).encode()
38 }
39
40 pub fn variant_scan(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> EncodedKeyRange {
41 EncodedKeyRange::start_end(
42 Some(Self::variant_start(namespace, sumtype, variant_tag)),
43 Some(Self::variant_end(namespace, sumtype, variant_tag)),
44 )
45 }
46
47 fn variant_start(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> EncodedKey {
48 let mut serializer = KeySerializer::with_capacity(18);
49 serializer.extend_u8(Self::KIND as u8).extend_u64(namespace).extend_u64(sumtype).extend_u8(variant_tag);
50 serializer.to_encoded_key()
51 }
52
53 fn variant_end(namespace: NamespaceId, sumtype: SumTypeId, variant_tag: u8) -> EncodedKey {
54 let mut serializer = KeySerializer::with_capacity(18);
55 serializer
56 .extend_u8(Self::KIND as u8)
57 .extend_u64(namespace)
58 .extend_u64(sumtype)
59 .extend_u8(variant_tag.wrapping_sub(1));
60 serializer.to_encoded_key()
61 }
62}
63
64impl EncodableKey for VariantHandlerKey {
65 const KIND: KeyKind = KeyKind::VariantHandler;
66
67 fn encode(&self) -> EncodedKey {
68 let mut serializer = KeySerializer::with_capacity(26);
69 serializer
70 .extend_u8(Self::KIND as u8)
71 .extend_u64(self.namespace)
72 .extend_u64(self.sumtype)
73 .extend_u8(self.variant_tag)
74 .extend_u64(self.handler);
75 serializer.to_encoded_key()
76 }
77
78 fn decode(key: &EncodedKey) -> Option<Self> {
79 let mut de = KeyDeserializer::from_bytes(key.as_slice());
80
81 let kind: KeyKind = de.read_u8().ok()?.try_into().ok()?;
82 if kind != Self::KIND {
83 return None;
84 }
85
86 let namespace = de.read_u64().ok()?;
87 let sumtype = de.read_u64().ok()?;
88 let variant_tag = de.read_u8().ok()?;
89 let handler = de.read_u64().ok()?;
90
91 Some(Self {
92 namespace: NamespaceId(namespace),
93 sumtype: SumTypeId(sumtype),
94 variant_tag,
95 handler: HandlerId(handler),
96 })
97 }
98}
99
100#[cfg(test)]
101pub mod tests {
102 use std::ops::Bound;
103
104 use reifydb_type::value::sumtype::SumTypeId;
105
106 use super::{EncodableKey, VariantHandlerKey};
107 use crate::interface::catalog::id::{HandlerId, NamespaceId};
108
109 #[test]
110 fn test_encode_decode() {
111 let key = VariantHandlerKey {
112 namespace: NamespaceId(0xABCD),
113 sumtype: SumTypeId(0x1234),
114 variant_tag: 5,
115 handler: HandlerId(0x6789),
116 };
117 let encoded = key.encode();
118 let expected: Vec<u8> = vec![0xCF, 0x3F, 0x54, 0x32, 0x6D, 0xCB, 0xFA, 0x3F, 0x98, 0x76];
119 assert_eq!(encoded.as_slice(), expected);
120
121 let decoded = VariantHandlerKey::decode(&encoded).unwrap();
122 assert_eq!(decoded.namespace, NamespaceId(0xABCD));
123 assert_eq!(decoded.sumtype, SumTypeId(0x1234));
124 assert_eq!(decoded.variant_tag, 5);
125 assert_eq!(decoded.handler, HandlerId(0x6789));
126 }
127
128 #[test]
129 fn test_order_preserving() {
130 let key1 = VariantHandlerKey {
131 namespace: NamespaceId::SYSTEM,
132 sumtype: SumTypeId(5),
133 variant_tag: 3,
134 handler: HandlerId(100),
135 };
136 let key2 = VariantHandlerKey {
137 namespace: NamespaceId::SYSTEM,
138 sumtype: SumTypeId(5),
139 variant_tag: 3,
140 handler: HandlerId(200),
141 };
142 let key3 = VariantHandlerKey {
143 namespace: NamespaceId::SYSTEM,
144 sumtype: SumTypeId(5),
145 variant_tag: 4,
146 handler: HandlerId(1),
147 };
148 let key4 = VariantHandlerKey {
149 namespace: NamespaceId::DEFAULT,
150 sumtype: SumTypeId(1),
151 variant_tag: 0,
152 handler: HandlerId(1),
153 };
154
155 let encoded1 = key1.encode();
156 let encoded2 = key2.encode();
157 let encoded3 = key3.encode();
158 let encoded4 = key4.encode();
159
160 assert!(encoded4 < encoded3, "ordering not preserved");
161 assert!(encoded3 < encoded2, "ordering not preserved");
162 assert!(encoded2 < encoded1, "ordering not preserved");
163 }
164
165 #[test]
166 fn test_variant_scan() {
167 let ns = NamespaceId::SYSTEM;
168 let st = SumTypeId(10);
169 let tag = 5u8;
170
171 let range = VariantHandlerKey::variant_scan(ns, st, tag);
172 let start = match &range.start {
173 Bound::Included(k) | Bound::Excluded(k) => k,
174 Bound::Unbounded => panic!("expected bounded start"),
175 };
176 let end = match &range.end {
177 Bound::Included(k) | Bound::Excluded(k) => k,
178 Bound::Unbounded => panic!("expected bounded end"),
179 };
180
181 let key = VariantHandlerKey {
182 namespace: ns,
183 sumtype: st,
184 variant_tag: tag,
185 handler: HandlerId(42),
186 };
187 let encoded = key.encode();
188 assert!(encoded.as_slice() >= start.as_slice());
189 assert!(encoded.as_slice() <= end.as_slice());
190
191 let other = VariantHandlerKey {
192 namespace: ns,
193 sumtype: st,
194 variant_tag: tag + 1,
195 handler: HandlerId(42),
196 };
197 let other_encoded = other.encode();
198 assert!(other_encoded.as_slice() < start.as_slice());
199 }
200}