Skip to main content

lattice_db/utils/
values.rs

1use bincode::{Decode, Encode};
2use rapidhash::v3::rapidhash_v3;
3
4use crate::errors::LatticeError;
5
6/// Value representation when stored inside the Graph.
7#[derive(Debug, Clone, PartialEq, Encode, Decode)]
8pub enum Primitive {
9    UInt(u64),
10    Text(String),
11}
12
13const PRIMITIVE_UINT: u64 = 1 << 56;
14const PRIMITIVE_TEXT: u64 = 2 << 56;
15
16impl Primitive {
17    /// Verify the value can be used as a Value for the graph.
18    pub fn verify(&self) -> Result<(), LatticeError> {
19        match self {
20            Primitive::UInt(n) => {
21                if (*n & 0xFF00000000000000) != 0 {
22                    return Err(LatticeError::NumberTooBig(n.to_string()));
23                }
24            }
25            Primitive::Text(_) => {}
26        }
27        Ok(())
28    }
29
30    /// Hashes the value.
31    /// * Value lookups are stored as hashes inside the database.
32    pub fn hash(&self) -> u64 {
33        match self {
34            Primitive::UInt(n) => *n | PRIMITIVE_UINT,
35            Primitive::Text(t) => {
36                (rapidhash_v3(t.as_bytes()) & 0x00FFFFFFFFFFFFFF) | PRIMITIVE_TEXT
37            }
38        }
39    }
40}
41
42/// Allows for storage inside the Graph.
43pub trait Value {
44    fn to_primitive(self) -> Primitive;
45}
46
47impl Value for u64 {
48    fn to_primitive(self) -> Primitive {
49        Primitive::UInt(self)
50    }
51}
52
53impl Value for u32 {
54    fn to_primitive(self) -> Primitive {
55        Primitive::UInt(self as u64)
56    }
57}
58
59impl Value for u16 {
60    fn to_primitive(self) -> Primitive {
61        Primitive::UInt(self as u64)
62    }
63}
64
65impl Value for u8 {
66    fn to_primitive(self) -> Primitive {
67        Primitive::UInt(self as u64)
68    }
69}
70
71impl Value for &str {
72    fn to_primitive(self) -> Primitive {
73        Primitive::Text(self.to_string())
74    }
75}