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 | KeyKind::NamespaceBinding => {
387				// Binding keys are used directly via EncodableKey trait, not through Key enum
388				None
389			}
390		}
391	}
392}
393
394#[cfg(test)]
395pub mod tests {
396	use reifydb_type::value::{row_number::RowNumber, sumtype::SumTypeId};
397
398	use crate::{
399		interface::catalog::{
400			flow::FlowNodeId,
401			id::{ColumnId, ColumnPropertyId, IndexId, NamespaceId, SequenceId, TableId},
402			shape::ShapeId,
403		},
404		key::{
405			Key, column::ColumnKey, column_sequence::ColumnSequenceKey, columns::ColumnsKey,
406			flow_node_state::FlowNodeStateKey, index::IndexKey, namespace::NamespaceKey,
407			namespace_sumtype::NamespaceSumTypeKey, namespace_table::NamespaceTableKey,
408			property::ColumnPropertyKey, row::RowKey, row_sequence::RowSequenceKey, sumtype::SumTypeKey,
409			system_sequence::SystemSequenceKey, table::TableKey,
410			transaction_version::TransactionVersionKey,
411		},
412	};
413
414	#[test]
415	fn test_table_columns() {
416		let key = Key::Columns(ColumnsKey {
417			column: ColumnId(42),
418		});
419
420		let encoded = key.encode();
421		let decoded = Key::decode(&encoded).expect("Failed to decode key");
422
423		match decoded {
424			Key::Columns(decoded_inner) => {
425				assert_eq!(decoded_inner.column, 42);
426			}
427			_ => unreachable!(),
428		}
429	}
430
431	#[test]
432	fn test_column() {
433		let key = Key::Column(ColumnKey {
434			shape: ShapeId::table(1),
435			column: ColumnId(42),
436		});
437
438		let encoded = key.encode();
439		let decoded = Key::decode(&encoded).expect("Failed to decode key");
440
441		match decoded {
442			Key::Column(decoded_inner) => {
443				assert_eq!(decoded_inner.shape, ShapeId::table(1));
444				assert_eq!(decoded_inner.column, 42);
445			}
446			_ => unreachable!(),
447		}
448	}
449
450	#[test]
451	fn test_column_property() {
452		let key = Key::TableColumnProperty(ColumnPropertyKey {
453			column: ColumnId(42),
454			property: ColumnPropertyId(999_999),
455		});
456
457		let encoded = key.encode();
458		let decoded = Key::decode(&encoded).expect("Failed to decode key");
459
460		match decoded {
461			Key::TableColumnProperty(decoded_inner) => {
462				assert_eq!(decoded_inner.column, 42);
463				assert_eq!(decoded_inner.property, 999_999);
464			}
465			_ => unreachable!(),
466		}
467	}
468
469	#[test]
470	fn test_namespace() {
471		let key = Key::Namespace(NamespaceKey {
472			namespace: NamespaceId(42),
473		});
474
475		let encoded = key.encode();
476		let decoded = Key::decode(&encoded).expect("Failed to decode key");
477
478		match decoded {
479			Key::Namespace(decoded_inner) => {
480				assert_eq!(decoded_inner.namespace, 42);
481			}
482			_ => unreachable!(),
483		}
484	}
485
486	#[test]
487	fn test_namespace_table() {
488		let key = Key::NamespaceTable(NamespaceTableKey {
489			namespace: NamespaceId(42),
490			table: TableId(999_999),
491		});
492
493		let encoded = key.encode();
494		let decoded = Key::decode(&encoded).expect("Failed to decode key");
495
496		match decoded {
497			Key::NamespaceTable(decoded_inner) => {
498				assert_eq!(decoded_inner.namespace, 42);
499				assert_eq!(decoded_inner.table, 999_999);
500			}
501			_ => unreachable!(),
502		}
503	}
504
505	#[test]
506	fn test_system_sequence() {
507		let key = Key::SystemSequence(SystemSequenceKey {
508			sequence: SequenceId(42),
509		});
510
511		let encoded = key.encode();
512		let decoded = Key::decode(&encoded).expect("Failed to decode key");
513
514		match decoded {
515			Key::SystemSequence(decoded_inner) => {
516				assert_eq!(decoded_inner.sequence, 42);
517			}
518			_ => unreachable!(),
519		}
520	}
521
522	#[test]
523	fn test_table() {
524		let key = Key::Table(TableKey {
525			table: TableId(42),
526		});
527
528		let encoded = key.encode();
529		let decoded = Key::decode(&encoded).expect("Failed to decode key");
530
531		match decoded {
532			Key::Table(decoded_inner) => {
533				assert_eq!(decoded_inner.table, 42);
534			}
535			_ => unreachable!(),
536		}
537	}
538
539	#[test]
540	fn test_index() {
541		let key = Key::Index(IndexKey {
542			shape: ShapeId::table(42),
543			index: IndexId::primary(999_999),
544		});
545
546		let encoded = key.encode();
547		let decoded = Key::decode(&encoded).expect("Failed to decode key");
548
549		match decoded {
550			Key::Index(decoded_inner) => {
551				assert_eq!(decoded_inner.shape, ShapeId::table(42));
552				assert_eq!(decoded_inner.index, 999_999);
553			}
554			_ => unreachable!(),
555		}
556	}
557
558	#[test]
559	fn test_row() {
560		let key = Key::Row(RowKey {
561			shape: ShapeId::table(42),
562			row: RowNumber(999_999),
563		});
564
565		let encoded = key.encode();
566		let decoded = Key::decode(&encoded).expect("Failed to decode key");
567
568		match decoded {
569			Key::Row(decoded_inner) => {
570				assert_eq!(decoded_inner.shape, ShapeId::table(42));
571				assert_eq!(decoded_inner.row, 999_999);
572			}
573			_ => unreachable!(),
574		}
575	}
576
577	#[test]
578	fn test_row_sequence() {
579		let key = Key::RowSequence(RowSequenceKey {
580			shape: ShapeId::table(42),
581		});
582
583		let encoded = key.encode();
584		let decoded = Key::decode(&encoded).expect("Failed to decode key");
585
586		match decoded {
587			Key::RowSequence(decoded_inner) => {
588				assert_eq!(decoded_inner.shape, ShapeId::table(42));
589			}
590			_ => unreachable!(),
591		}
592	}
593
594	#[test]
595	fn test_column_sequence() {
596		let key = Key::TableColumnSequence(ColumnSequenceKey {
597			shape: ShapeId::table(42),
598			column: ColumnId(123),
599		});
600
601		let encoded = key.encode();
602		let decoded = Key::decode(&encoded).expect("Failed to decode key");
603
604		match decoded {
605			Key::TableColumnSequence(decoded_inner) => {
606				assert_eq!(decoded_inner.shape, ShapeId::table(42));
607				assert_eq!(decoded_inner.column, 123);
608			}
609			_ => unreachable!(),
610		}
611	}
612
613	#[test]
614	fn test_transaction_version() {
615		let key = Key::TransactionVersion(TransactionVersionKey {});
616		let encoded = key.encode();
617		Key::decode(&encoded).expect("Failed to decode key");
618	}
619
620	#[test]
621	fn test_operator_state() {
622		let key = Key::FlowNodeState(FlowNodeStateKey {
623			node: FlowNodeId(0xCAFEBABE),
624			key: vec![1, 2, 3],
625		});
626
627		let encoded = key.encode();
628		let decoded = Key::decode(&encoded).expect("Failed to decode key");
629
630		match decoded {
631			Key::FlowNodeState(decoded_inner) => {
632				assert_eq!(decoded_inner.node, 0xCAFEBABE);
633				assert_eq!(decoded_inner.key, vec![1, 2, 3]);
634			}
635			_ => unreachable!(),
636		}
637	}
638
639	#[test]
640	fn test_sumtype_key() {
641		let key = Key::SumType(SumTypeKey {
642			sumtype: SumTypeId(42),
643		});
644
645		let encoded = key.encode();
646		let decoded = Key::decode(&encoded).expect("Failed to decode key");
647
648		match decoded {
649			Key::SumType(decoded_inner) => {
650				assert_eq!(decoded_inner.sumtype, 42);
651			}
652			_ => unreachable!(),
653		}
654	}
655
656	#[test]
657	fn test_namespace_sumtype_key() {
658		let key = Key::NamespaceSumType(NamespaceSumTypeKey {
659			namespace: NamespaceId(42),
660			sumtype: SumTypeId(999_999),
661		});
662
663		let encoded = key.encode();
664		let decoded = Key::decode(&encoded).expect("Failed to decode key");
665
666		match decoded {
667			Key::NamespaceSumType(decoded_inner) => {
668				assert_eq!(decoded_inner.namespace, 42);
669				assert_eq!(decoded_inner.sumtype, 999_999);
670			}
671			_ => unreachable!(),
672		}
673	}
674}