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