Skip to main content

reifydb_core/key/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use authentication::AuthenticationKey;
5use binding::BindingKey;
6use cdc_consumer::CdcConsumerKey;
7use column::ColumnKey;
8use column_sequence::ColumnSequenceKey;
9use columns::ColumnsKey;
10use dictionary::{DictionaryEntryIndexKey, DictionaryEntryKey, DictionaryKey, DictionarySequenceKey};
11use flow::FlowKey;
12use flow_node_internal_state::FlowNodeInternalStateKey;
13use flow_node_state::FlowNodeStateKey;
14use granted_role::GrantedRoleKey;
15use handler::HandlerKey;
16use identity::IdentityKey;
17use index::IndexKey;
18use index_entry::IndexEntryKey;
19use kind::KeyKind;
20use namespace::NamespaceKey;
21use namespace_binding::NamespaceBindingKey;
22use namespace_dictionary::NamespaceDictionaryKey;
23use namespace_flow::NamespaceFlowKey;
24use namespace_handler::NamespaceHandlerKey;
25use namespace_procedure::NamespaceProcedureKey;
26use namespace_ringbuffer::NamespaceRingBufferKey;
27use namespace_series::NamespaceSeriesKey;
28use namespace_sink::NamespaceSinkKey;
29use namespace_source::NamespaceSourceKey;
30use namespace_sumtype::NamespaceSumTypeKey;
31use namespace_table::NamespaceTableKey;
32use namespace_view::NamespaceViewKey;
33use policy::PolicyKey;
34use policy_op::PolicyOpKey;
35use primary_key::PrimaryKeyKey;
36use procedure::ProcedureKey;
37use procedure_param::ProcedureParamKey;
38use property::ColumnPropertyKey;
39use retention_strategy::{OperatorRetentionStrategyKey, ShapeRetentionStrategyKey};
40use ringbuffer::{RingBufferKey, RingBufferMetadataKey};
41use role::RoleKey;
42use row::RowKey;
43use row_sequence::RowSequenceKey;
44use series::{SeriesKey, SeriesMetadataKey};
45use sink::SinkKey;
46use source::SourceKey;
47use sumtype::SumTypeKey;
48use system_sequence::SystemSequenceKey;
49use system_version::SystemVersionKey;
50use table::TableKey;
51use token::TokenKey;
52use transaction_version::TransactionVersionKey;
53use view::ViewKey;
54
55use crate::{
56	encoded::key::{EncodedKey, EncodedKeyRange},
57	util::encoding::keycode,
58};
59
60pub mod authentication;
61pub mod binding;
62pub mod cdc_consumer;
63pub mod cdc_exclude;
64pub mod column;
65pub mod column_sequence;
66pub mod columns;
67pub mod config;
68pub mod dictionary;
69pub mod flow;
70pub mod flow_edge;
71pub mod flow_node;
72pub mod flow_node_internal_state;
73pub mod flow_node_state;
74pub mod flow_version;
75pub mod granted_role;
76pub mod handler;
77pub mod identity;
78pub mod index;
79pub mod index_entry;
80pub mod kind;
81pub mod migration;
82pub mod migration_event;
83pub mod namespace;
84pub mod namespace_binding;
85pub mod namespace_dictionary;
86pub mod namespace_flow;
87pub mod namespace_handler;
88pub mod namespace_procedure;
89pub mod namespace_ringbuffer;
90pub mod namespace_series;
91pub mod namespace_sink;
92pub mod namespace_source;
93pub mod namespace_sumtype;
94pub mod namespace_table;
95pub mod namespace_view;
96pub mod policy;
97pub mod policy_op;
98pub mod primary_key;
99pub mod procedure;
100pub mod procedure_param;
101pub mod property;
102pub mod retention_strategy;
103pub mod ringbuffer;
104pub mod role;
105pub mod row;
106pub mod row_sequence;
107pub mod series;
108pub mod series_row;
109pub mod shape;
110pub mod sink;
111pub mod source;
112pub mod sumtype;
113pub mod system_sequence;
114pub mod system_version;
115pub mod table;
116pub mod token;
117pub mod transaction_version;
118pub mod ttl;
119pub mod variant_handler;
120pub mod view;
121#[derive(Debug)]
122pub enum Key {
123	CdcConsumer(CdcConsumerKey),
124	Namespace(NamespaceKey),
125	NamespaceTable(NamespaceTableKey),
126	NamespaceView(NamespaceViewKey),
127	NamespaceFlow(NamespaceFlowKey),
128	SystemSequence(SystemSequenceKey),
129	Table(TableKey),
130	Flow(FlowKey),
131	Column(ColumnKey),
132	Columns(ColumnsKey),
133	Index(IndexKey),
134	IndexEntry(IndexEntryKey),
135	FlowNodeState(FlowNodeStateKey),
136	FlowNodeInternalState(FlowNodeInternalStateKey),
137	PrimaryKey(PrimaryKeyKey),
138	Row(RowKey),
139	RowSequence(RowSequenceKey),
140	TableColumnSequence(ColumnSequenceKey),
141	TableColumnProperty(ColumnPropertyKey),
142	SystemVersion(SystemVersionKey),
143	TransactionVersion(TransactionVersionKey),
144	View(ViewKey),
145	RingBuffer(RingBufferKey),
146	RingBufferMetadata(RingBufferMetadataKey),
147	NamespaceRingBuffer(NamespaceRingBufferKey),
148	ShapeRetentionStrategy(ShapeRetentionStrategyKey),
149	OperatorRetentionStrategy(OperatorRetentionStrategyKey),
150	Dictionary(DictionaryKey),
151	DictionaryEntry(DictionaryEntryKey),
152	DictionaryEntryIndex(DictionaryEntryIndexKey),
153	DictionarySequence(DictionarySequenceKey),
154	NamespaceDictionary(NamespaceDictionaryKey),
155	SumType(SumTypeKey),
156	NamespaceSumType(NamespaceSumTypeKey),
157	Handler(HandlerKey),
158	NamespaceHandler(NamespaceHandlerKey),
159	Series(SeriesKey),
160	SeriesMetadata(SeriesMetadataKey),
161	NamespaceSeries(NamespaceSeriesKey),
162	Identity(IdentityKey),
163	Authentication(AuthenticationKey),
164	Role(RoleKey),
165	GrantedRole(GrantedRoleKey),
166	Policy(PolicyKey),
167	PolicyOp(PolicyOpKey),
168	Token(TokenKey),
169	Source(SourceKey),
170	NamespaceSource(NamespaceSourceKey),
171	Sink(SinkKey),
172	NamespaceSink(NamespaceSinkKey),
173	Procedure(ProcedureKey),
174	NamespaceProcedure(NamespaceProcedureKey),
175	ProcedureParam(ProcedureParamKey),
176	Binding(BindingKey),
177	NamespaceBinding(NamespaceBindingKey),
178}
179
180impl Key {
181	pub fn encode(&self) -> EncodedKey {
182		match &self {
183			Key::CdcConsumer(key) => key.encode(),
184			Key::Namespace(key) => key.encode(),
185			Key::NamespaceTable(key) => key.encode(),
186			Key::NamespaceView(key) => key.encode(),
187			Key::NamespaceFlow(key) => key.encode(),
188			Key::Table(key) => key.encode(),
189			Key::Flow(key) => key.encode(),
190			Key::Column(key) => key.encode(),
191			Key::Columns(key) => key.encode(),
192			Key::TableColumnProperty(key) => key.encode(),
193			Key::Index(key) => key.encode(),
194			Key::IndexEntry(key) => key.encode(),
195			Key::FlowNodeState(key) => key.encode(),
196			Key::FlowNodeInternalState(key) => key.encode(),
197			Key::PrimaryKey(key) => key.encode(),
198			Key::Row(key) => key.encode(),
199			Key::RowSequence(key) => key.encode(),
200			Key::TableColumnSequence(key) => key.encode(),
201			Key::SystemSequence(key) => key.encode(),
202			Key::SystemVersion(key) => key.encode(),
203			Key::TransactionVersion(key) => key.encode(),
204			Key::View(key) => key.encode(),
205			Key::RingBuffer(key) => key.encode(),
206			Key::RingBufferMetadata(key) => key.encode(),
207			Key::NamespaceRingBuffer(key) => key.encode(),
208			Key::ShapeRetentionStrategy(key) => key.encode(),
209			Key::OperatorRetentionStrategy(key) => key.encode(),
210			Key::Dictionary(key) => key.encode(),
211			Key::DictionaryEntry(key) => key.encode(),
212			Key::DictionaryEntryIndex(key) => key.encode(),
213			Key::DictionarySequence(key) => key.encode(),
214			Key::NamespaceDictionary(key) => key.encode(),
215			Key::SumType(key) => key.encode(),
216			Key::NamespaceSumType(key) => key.encode(),
217			Key::Handler(key) => key.encode(),
218			Key::NamespaceHandler(key) => key.encode(),
219			Key::Series(key) => key.encode(),
220			Key::SeriesMetadata(key) => key.encode(),
221			Key::NamespaceSeries(key) => key.encode(),
222			Key::Identity(key) => key.encode(),
223			Key::Authentication(key) => key.encode(),
224			Key::Role(key) => key.encode(),
225			Key::GrantedRole(key) => key.encode(),
226			Key::Policy(key) => key.encode(),
227			Key::PolicyOp(key) => key.encode(),
228			Key::Token(key) => key.encode(),
229			Key::Source(key) => key.encode(),
230			Key::NamespaceSource(key) => key.encode(),
231			Key::Sink(key) => key.encode(),
232			Key::NamespaceSink(key) => key.encode(),
233			Key::Procedure(key) => key.encode(),
234			Key::NamespaceProcedure(key) => key.encode(),
235			Key::ProcedureParam(key) => key.encode(),
236			Key::Binding(key) => key.encode(),
237			Key::NamespaceBinding(key) => key.encode(),
238		}
239	}
240}
241
242pub trait EncodableKey {
243	const KIND: KeyKind;
244
245	fn encode(&self) -> EncodedKey;
246
247	fn decode(key: &EncodedKey) -> Option<Self>
248	where
249		Self: Sized;
250}
251
252pub trait EncodableKeyRange {
253	const KIND: KeyKind;
254
255	fn start(&self) -> Option<EncodedKey>;
256
257	fn end(&self) -> Option<EncodedKey>;
258
259	fn decode(range: &EncodedKeyRange) -> (Option<Self>, Option<Self>)
260	where
261		Self: Sized;
262}
263
264impl Key {
265	pub fn kind(key: impl AsRef<[u8]>) -> Option<KeyKind> {
266		let key = key.as_ref();
267		if key.len() < 2 {
268			return None;
269		}
270
271		keycode::deserialize(&key[1..2]).ok()
272	}
273
274	pub fn decode(key: &EncodedKey) -> Option<Self> {
275		if key.len() < 2 {
276			return None;
277		}
278
279		let kind: KeyKind = keycode::deserialize(&key[1..2]).ok()?;
280		match kind {
281			KeyKind::CdcConsumer => CdcConsumerKey::decode(key).map(Self::CdcConsumer),
282			KeyKind::Columns => ColumnsKey::decode(key).map(Self::Columns),
283			KeyKind::ColumnProperty => ColumnPropertyKey::decode(key).map(Self::TableColumnProperty),
284			KeyKind::Namespace => NamespaceKey::decode(key).map(Self::Namespace),
285			KeyKind::NamespaceTable => NamespaceTableKey::decode(key).map(Self::NamespaceTable),
286			KeyKind::NamespaceView => NamespaceViewKey::decode(key).map(Self::NamespaceView),
287			KeyKind::NamespaceFlow => NamespaceFlowKey::decode(key).map(Self::NamespaceFlow),
288			KeyKind::Table => TableKey::decode(key).map(Self::Table),
289			KeyKind::Flow => FlowKey::decode(key).map(Self::Flow),
290			KeyKind::Column => ColumnKey::decode(key).map(Self::Column),
291			KeyKind::Index => IndexKey::decode(key).map(Self::Index),
292			KeyKind::IndexEntry => IndexEntryKey::decode(key).map(Self::IndexEntry),
293			KeyKind::FlowNodeState => FlowNodeStateKey::decode(key).map(Self::FlowNodeState),
294			KeyKind::FlowNodeInternalState => {
295				FlowNodeInternalStateKey::decode(key).map(Self::FlowNodeInternalState)
296			}
297			KeyKind::Row => RowKey::decode(key).map(Self::Row),
298			KeyKind::RowSequence => RowSequenceKey::decode(key).map(Self::RowSequence),
299			KeyKind::ColumnSequence => ColumnSequenceKey::decode(key).map(Self::TableColumnSequence),
300			KeyKind::SystemSequence => SystemSequenceKey::decode(key).map(Self::SystemSequence),
301			KeyKind::SystemVersion => SystemVersionKey::decode(key).map(Self::SystemVersion),
302			KeyKind::TransactionVersion => TransactionVersionKey::decode(key).map(Self::TransactionVersion),
303			KeyKind::View => ViewKey::decode(key).map(Self::View),
304			KeyKind::PrimaryKey => PrimaryKeyKey::decode(key).map(Self::PrimaryKey),
305			KeyKind::RingBuffer => RingBufferKey::decode(key).map(Self::RingBuffer),
306			KeyKind::RingBufferMetadata => RingBufferMetadataKey::decode(key).map(Self::RingBufferMetadata),
307			KeyKind::NamespaceRingBuffer => {
308				NamespaceRingBufferKey::decode(key).map(Self::NamespaceRingBuffer)
309			}
310			KeyKind::ShapeRetentionStrategy => {
311				ShapeRetentionStrategyKey::decode(key).map(Self::ShapeRetentionStrategy)
312			}
313			KeyKind::OperatorRetentionStrategy => {
314				OperatorRetentionStrategyKey::decode(key).map(Self::OperatorRetentionStrategy)
315			}
316			KeyKind::FlowNode
317			| KeyKind::FlowNodeByFlow
318			| KeyKind::FlowEdge
319			| KeyKind::FlowEdgeByFlow
320			| KeyKind::FlowVersion => {
321				// These keys are used directly via EncodableKey trait, not through Key enum
322				None
323			}
324			KeyKind::Dictionary => DictionaryKey::decode(key).map(Self::Dictionary),
325			KeyKind::DictionaryEntry => DictionaryEntryKey::decode(key).map(Self::DictionaryEntry),
326			KeyKind::DictionaryEntryIndex => {
327				DictionaryEntryIndexKey::decode(key).map(Self::DictionaryEntryIndex)
328			}
329			KeyKind::DictionarySequence => DictionarySequenceKey::decode(key).map(Self::DictionarySequence),
330			KeyKind::NamespaceDictionary => {
331				NamespaceDictionaryKey::decode(key).map(Self::NamespaceDictionary)
332			}
333			KeyKind::SumType => SumTypeKey::decode(key).map(Self::SumType),
334			KeyKind::NamespaceSumType => NamespaceSumTypeKey::decode(key).map(Self::NamespaceSumType),
335			KeyKind::Handler => HandlerKey::decode(key).map(Self::Handler),
336			KeyKind::NamespaceHandler => NamespaceHandlerKey::decode(key).map(Self::NamespaceHandler),
337			KeyKind::VariantHandler => {
338				// VariantHandler keys used directly via EncodableKey trait
339				None
340			}
341			KeyKind::Metric => {
342				// Storage tracker keys are used for internal persistence, not through Key enum
343				None
344			}
345			KeyKind::Subscription | KeyKind::SubscriptionColumn | KeyKind::SubscriptionRow => {
346				// Subscription storage keys have been removed (ephemeral subscriptions only)
347				None
348			}
349			KeyKind::Shape | KeyKind::RowShapeField => {
350				// Shape keys are used directly via EncodableKey trait, not through Key enum
351				None
352			}
353			KeyKind::Series => SeriesKey::decode(key).map(Self::Series),
354			KeyKind::NamespaceSeries => NamespaceSeriesKey::decode(key).map(Self::NamespaceSeries),
355			KeyKind::SeriesMetadata => SeriesMetadataKey::decode(key).map(Self::SeriesMetadata),
356			KeyKind::Identity => IdentityKey::decode(key).map(Self::Identity),
357			KeyKind::Authentication => AuthenticationKey::decode(key).map(Self::Authentication),
358			KeyKind::Role => RoleKey::decode(key).map(Self::Role),
359			KeyKind::GrantedRole => GrantedRoleKey::decode(key).map(Self::GrantedRole),
360			KeyKind::Policy => PolicyKey::decode(key).map(Self::Policy),
361			KeyKind::PolicyOp => PolicyOpKey::decode(key).map(Self::PolicyOp),
362			KeyKind::Migration | KeyKind::MigrationEvent => {
363				// Migration keys are used directly via EncodableKey trait, not through Key enum
364				None
365			}
366			KeyKind::Token => TokenKey::decode(key).map(Self::Token),
367			KeyKind::ConfigStorage => {
368				// Config keys are used directly via EncodableKey trait, not through Key enum
369				None
370			}
371			KeyKind::Source
372			| KeyKind::NamespaceSource
373			| KeyKind::Sink
374			| KeyKind::NamespaceSink
375			| KeyKind::SourceCheckpoint => {
376				// Source/Sink keys are used directly via EncodableKey trait, not through Key enum
377				None
378			}
379			KeyKind::RowTtl => {
380				// RowTtl keys are used directly via EncodableKey trait, not through Key enum
381				None
382			}
383			KeyKind::Procedure => ProcedureKey::decode(key).map(Self::Procedure),
384			KeyKind::NamespaceProcedure => NamespaceProcedureKey::decode(key).map(Self::NamespaceProcedure),
385			KeyKind::ProcedureParam => ProcedureParamKey::decode(key).map(Self::ProcedureParam),
386			KeyKind::Binding => BindingKey::decode(key).map(Self::Binding),
387			KeyKind::NamespaceBinding => {
388				// NamespaceBinding keys are used directly via EncodableKey trait, not through Key enum
389				None
390			}
391		}
392	}
393}
394
395#[cfg(test)]
396pub mod tests {
397	use reifydb_type::value::{row_number::RowNumber, sumtype::SumTypeId};
398
399	use crate::{
400		interface::catalog::{
401			flow::FlowNodeId,
402			id::{ColumnId, ColumnPropertyId, IndexId, NamespaceId, SequenceId, TableId},
403			shape::ShapeId,
404		},
405		key::{
406			Key, column::ColumnKey, column_sequence::ColumnSequenceKey, columns::ColumnsKey,
407			flow_node_state::FlowNodeStateKey, index::IndexKey, namespace::NamespaceKey,
408			namespace_sumtype::NamespaceSumTypeKey, namespace_table::NamespaceTableKey,
409			property::ColumnPropertyKey, row::RowKey, row_sequence::RowSequenceKey, sumtype::SumTypeKey,
410			system_sequence::SystemSequenceKey, table::TableKey,
411			transaction_version::TransactionVersionKey,
412		},
413	};
414
415	#[test]
416	fn test_table_columns() {
417		let key = Key::Columns(ColumnsKey {
418			column: ColumnId(42),
419		});
420
421		let encoded = key.encode();
422		let decoded = Key::decode(&encoded).expect("Failed to decode key");
423
424		match decoded {
425			Key::Columns(decoded_inner) => {
426				assert_eq!(decoded_inner.column, 42);
427			}
428			_ => unreachable!(),
429		}
430	}
431
432	#[test]
433	fn test_column() {
434		let key = Key::Column(ColumnKey {
435			shape: ShapeId::table(1),
436			column: ColumnId(42),
437		});
438
439		let encoded = key.encode();
440		let decoded = Key::decode(&encoded).expect("Failed to decode key");
441
442		match decoded {
443			Key::Column(decoded_inner) => {
444				assert_eq!(decoded_inner.shape, ShapeId::table(1));
445				assert_eq!(decoded_inner.column, 42);
446			}
447			_ => unreachable!(),
448		}
449	}
450
451	#[test]
452	fn test_column_property() {
453		let key = Key::TableColumnProperty(ColumnPropertyKey {
454			column: ColumnId(42),
455			property: ColumnPropertyId(999_999),
456		});
457
458		let encoded = key.encode();
459		let decoded = Key::decode(&encoded).expect("Failed to decode key");
460
461		match decoded {
462			Key::TableColumnProperty(decoded_inner) => {
463				assert_eq!(decoded_inner.column, 42);
464				assert_eq!(decoded_inner.property, 999_999);
465			}
466			_ => unreachable!(),
467		}
468	}
469
470	#[test]
471	fn test_namespace() {
472		let key = Key::Namespace(NamespaceKey {
473			namespace: NamespaceId(42),
474		});
475
476		let encoded = key.encode();
477		let decoded = Key::decode(&encoded).expect("Failed to decode key");
478
479		match decoded {
480			Key::Namespace(decoded_inner) => {
481				assert_eq!(decoded_inner.namespace, 42);
482			}
483			_ => unreachable!(),
484		}
485	}
486
487	#[test]
488	fn test_namespace_table() {
489		let key = Key::NamespaceTable(NamespaceTableKey {
490			namespace: NamespaceId(42),
491			table: TableId(999_999),
492		});
493
494		let encoded = key.encode();
495		let decoded = Key::decode(&encoded).expect("Failed to decode key");
496
497		match decoded {
498			Key::NamespaceTable(decoded_inner) => {
499				assert_eq!(decoded_inner.namespace, 42);
500				assert_eq!(decoded_inner.table, 999_999);
501			}
502			_ => unreachable!(),
503		}
504	}
505
506	#[test]
507	fn test_system_sequence() {
508		let key = Key::SystemSequence(SystemSequenceKey {
509			sequence: SequenceId(42),
510		});
511
512		let encoded = key.encode();
513		let decoded = Key::decode(&encoded).expect("Failed to decode key");
514
515		match decoded {
516			Key::SystemSequence(decoded_inner) => {
517				assert_eq!(decoded_inner.sequence, 42);
518			}
519			_ => unreachable!(),
520		}
521	}
522
523	#[test]
524	fn test_table() {
525		let key = Key::Table(TableKey {
526			table: TableId(42),
527		});
528
529		let encoded = key.encode();
530		let decoded = Key::decode(&encoded).expect("Failed to decode key");
531
532		match decoded {
533			Key::Table(decoded_inner) => {
534				assert_eq!(decoded_inner.table, 42);
535			}
536			_ => unreachable!(),
537		}
538	}
539
540	#[test]
541	fn test_index() {
542		let key = Key::Index(IndexKey {
543			shape: ShapeId::table(42),
544			index: IndexId::primary(999_999),
545		});
546
547		let encoded = key.encode();
548		let decoded = Key::decode(&encoded).expect("Failed to decode key");
549
550		match decoded {
551			Key::Index(decoded_inner) => {
552				assert_eq!(decoded_inner.shape, ShapeId::table(42));
553				assert_eq!(decoded_inner.index, 999_999);
554			}
555			_ => unreachable!(),
556		}
557	}
558
559	#[test]
560	fn test_row() {
561		let key = Key::Row(RowKey {
562			shape: ShapeId::table(42),
563			row: RowNumber(999_999),
564		});
565
566		let encoded = key.encode();
567		let decoded = Key::decode(&encoded).expect("Failed to decode key");
568
569		match decoded {
570			Key::Row(decoded_inner) => {
571				assert_eq!(decoded_inner.shape, ShapeId::table(42));
572				assert_eq!(decoded_inner.row, 999_999);
573			}
574			_ => unreachable!(),
575		}
576	}
577
578	#[test]
579	fn test_row_sequence() {
580		let key = Key::RowSequence(RowSequenceKey {
581			shape: ShapeId::table(42),
582		});
583
584		let encoded = key.encode();
585		let decoded = Key::decode(&encoded).expect("Failed to decode key");
586
587		match decoded {
588			Key::RowSequence(decoded_inner) => {
589				assert_eq!(decoded_inner.shape, ShapeId::table(42));
590			}
591			_ => unreachable!(),
592		}
593	}
594
595	#[test]
596	fn test_column_sequence() {
597		let key = Key::TableColumnSequence(ColumnSequenceKey {
598			shape: ShapeId::table(42),
599			column: ColumnId(123),
600		});
601
602		let encoded = key.encode();
603		let decoded = Key::decode(&encoded).expect("Failed to decode key");
604
605		match decoded {
606			Key::TableColumnSequence(decoded_inner) => {
607				assert_eq!(decoded_inner.shape, ShapeId::table(42));
608				assert_eq!(decoded_inner.column, 123);
609			}
610			_ => unreachable!(),
611		}
612	}
613
614	#[test]
615	fn test_transaction_version() {
616		let key = Key::TransactionVersion(TransactionVersionKey {});
617		let encoded = key.encode();
618		Key::decode(&encoded).expect("Failed to decode key");
619	}
620
621	#[test]
622	fn test_operator_state() {
623		let key = Key::FlowNodeState(FlowNodeStateKey {
624			node: FlowNodeId(0xCAFEBABE),
625			key: vec![1, 2, 3],
626		});
627
628		let encoded = key.encode();
629		let decoded = Key::decode(&encoded).expect("Failed to decode key");
630
631		match decoded {
632			Key::FlowNodeState(decoded_inner) => {
633				assert_eq!(decoded_inner.node, 0xCAFEBABE);
634				assert_eq!(decoded_inner.key, vec![1, 2, 3]);
635			}
636			_ => unreachable!(),
637		}
638	}
639
640	#[test]
641	fn test_sumtype_key() {
642		let key = Key::SumType(SumTypeKey {
643			sumtype: SumTypeId(42),
644		});
645
646		let encoded = key.encode();
647		let decoded = Key::decode(&encoded).expect("Failed to decode key");
648
649		match decoded {
650			Key::SumType(decoded_inner) => {
651				assert_eq!(decoded_inner.sumtype, 42);
652			}
653			_ => unreachable!(),
654		}
655	}
656
657	#[test]
658	fn test_namespace_sumtype_key() {
659		let key = Key::NamespaceSumType(NamespaceSumTypeKey {
660			namespace: NamespaceId(42),
661			sumtype: SumTypeId(999_999),
662		});
663
664		let encoded = key.encode();
665		let decoded = Key::decode(&encoded).expect("Failed to decode key");
666
667		match decoded {
668			Key::NamespaceSumType(decoded_inner) => {
669				assert_eq!(decoded_inner.namespace, 42);
670				assert_eq!(decoded_inner.sumtype, 999_999);
671			}
672			_ => unreachable!(),
673		}
674	}
675}