@@ -5,12 +5,17 @@ use core::cmp::Ordering;
55use core:: hash:: { Hash , Hasher } ;
66use core:: mem;
77use core:: ops:: Deref ;
8- use spacetimedb_lib:: buffer:: { CountWriter , TeeWriter } ;
8+ use spacetimedb_lib:: de:: ProductVisitor ;
9+ use spacetimedb_lib:: ser:: { SerializeSeqProduct , Serializer as _} ;
910use spacetimedb_memory_usage:: MemoryUsage ;
1011use spacetimedb_primitives:: ColList ;
12+ use spacetimedb_sats:: algebraic_value:: de:: { ValueDeserializeError , ValueDeserializer } ;
1113use spacetimedb_sats:: bsatn:: { DecodeError , Deserializer , Serializer } ;
14+ use spacetimedb_sats:: buffer:: { CountWriter , TeeWriter } ;
1215use spacetimedb_sats:: de:: { DeserializeSeed , Error as _} ;
13- use spacetimedb_sats:: { i256, u256, AlgebraicType , AlgebraicValue , ProductTypeElement , Serialize as _, WithTypespace } ;
16+ use spacetimedb_sats:: {
17+ i256, u256, AlgebraicType , AlgebraicValue , ProductTypeElement , ProductValue , Serialize as _, WithTypespace ,
18+ } ;
1419
1520/// A key for an all-primitive multi-column index
1621/// serialized to a byte array.
@@ -418,6 +423,66 @@ impl<const N: usize> RangeCompatBytesKey<N> {
418423 Self :: from_bytes_key ( key, ty)
419424 }
420425
426+ /// Decodes `prefix` in `AlgebraicValue` form to a [`RangeCompatBytesKey<N>`]
427+ /// by serializing the prefix and massaging.
428+ pub ( super ) fn from_algebraic_value_prefix (
429+ prefix : & ProductValue ,
430+ prefix_types : & [ ProductTypeElement ] ,
431+ ) -> Result < Self , ValueDeserializeError > {
432+ // Validate the prefix.
433+ WithTypespace :: empty ( prefix_types) . validate_seq_product ( ValueDeserializer :: from_product_ref ( prefix) ) ?;
434+
435+ // Serialize the `prefix` and the `endpoint` over.
436+ let bytes = BytesKey :: via_serializer ( |ser| {
437+ prefix
438+ . serialize ( ser)
439+ . expect ( "should've serialized to BSATN successfully" ) ;
440+ } ) ;
441+ let BytesKey { mut bytes, length } = bytes;
442+
443+ // Massage the bytes.
444+ let mut slice = bytes. as_mut_slice ( ) ;
445+ for ty in prefix_types {
446+ slice = Self :: process_from_bytes_key ( slice, & ty. algebraic_type ) ;
447+ }
448+
449+ Ok ( Self :: new ( length as usize , bytes) )
450+ }
451+
452+ /// Decodes `prefix` and `endpoint` in `AlgebraicValue` form to a [`RangeCompatBytesKey<N>`]
453+ /// by serializing over both and massaging if they fit into the key.
454+ pub ( super ) fn from_algebraic_value_prefix_and_endpoint (
455+ prefix : & ProductValue ,
456+ prefix_types : & [ ProductTypeElement ] ,
457+ endpoint : & AlgebraicValue ,
458+ range_type : & AlgebraicType ,
459+ ) -> Result < Self , ValueDeserializeError > {
460+ // Validate the values.
461+ WithTypespace :: empty ( prefix_types) . validate_seq_product ( ValueDeserializer :: from_product_ref ( prefix) ) ?;
462+ WithTypespace :: empty ( range_type) . validate ( ValueDeserializer :: from_ref ( endpoint) ) ?;
463+
464+ // Serialize the `prefix` and the `endpoint` over.
465+ let bytes = BytesKey :: via_serializer ( |ser| {
466+ ( || {
467+ let mut ser = ser. serialize_seq_product ( 2 ) ?;
468+ ser. serialize_element ( & prefix) ?;
469+ ser. serialize_element ( & endpoint) ?;
470+ ser. end ( )
471+ } ) ( )
472+ . expect ( "should've serialized to BSATN successfully" ) ;
473+ } ) ;
474+ let BytesKey { mut bytes, length } = bytes;
475+
476+ // Massage the bytes.
477+ let mut slice = bytes. as_mut_slice ( ) ;
478+ for ty in prefix_types {
479+ slice = Self :: process_from_bytes_key ( slice, & ty. algebraic_type ) ;
480+ }
481+ Self :: process_from_bytes_key ( slice, range_type) ;
482+
483+ Ok ( Self :: new ( length as usize , bytes) )
484+ }
485+
421486 /// Serializes `av` to a [`BytesKey<N>`].
422487 ///
423488 /// It's assumed that `av`
0 commit comments