reifydb_codec/primitive/
digest.rs1use reifydb_value::{
5 reifydb_assertions,
6 value::{digest::Digest, value_type::ValueType},
7};
8
9use crate::row::{bytes::RowBuilder, shape::RowShape};
10
11impl RowShape {
12 pub fn set_digest(&self, row: &mut impl RowBuilder, index: usize, value: &Digest) {
13 reifydb_assertions! {
14 assert!(
15 row.len() >= self.total_static_size(),
16 "row/shape size mismatch: row.len()={} < total_static_size()={}",
17 row.len(),
18 self.total_static_size()
19 );
20 }
21 self.check_digest_type(index, value);
22 self.replace_dynamic_data(row, index, &value.encode());
23 }
24
25 pub fn get_digest(&self, row: &[u8], index: usize) -> Digest {
26 let field = &self.fields()[index];
27 reifydb_assertions! {
28 assert!(
29 row.len() >= self.total_static_size(),
30 "row/shape size mismatch: row.len()={} < total_static_size()={}",
31 row.len(),
32 self.total_static_size()
33 );
34 }
35
36 let ref_slice = &row[field.offset as usize..field.offset as usize + 8];
37 let offset = u32::from_le_bytes([ref_slice[0], ref_slice[1], ref_slice[2], ref_slice[3]]) as usize;
38 let length = u32::from_le_bytes([ref_slice[4], ref_slice[5], ref_slice[6], ref_slice[7]]) as usize;
39
40 let data_start = self.dynamic_section_start() + offset;
41 let bytes = row.get(data_start..data_start + length).unwrap_or_else(|| {
42 panic!(
43 "corrupt digest in column {:?}: bytes {data_start}..{} lie outside the {}-byte row",
44 field.name,
45 data_start + length,
46 row.len()
47 )
48 });
49 let digest = Digest::decode(bytes)
50 .unwrap_or_else(|error| panic!("corrupt digest in column {:?}: {error}", field.name));
51 self.check_digest_type(index, &digest);
52 digest
53 }
54
55 fn check_digest_type(&self, index: usize, digest: &Digest) {
56 let field = &self.fields()[index];
57 match field.constraint.get_type().inner_type() {
58 ValueType::Digest {
59 inner,
60 accuracy,
61 } if **inner == *digest.inner() && *accuracy == digest.accuracy() => {}
62 declared => panic!(
63 "column {:?} of type {declared} cannot hold a {}",
64 field.name,
65 ValueType::Digest {
66 inner: Box::new(digest.inner().clone()),
67 accuracy: digest.accuracy(),
68 }
69 ),
70 }
71 }
72}