Skip to main content

lib_bcsv_jmap/
entry.rs

1//! Entry (row) implementation for JMap containers
2
3use std::collections::HashMap;
4
5use crate::field::FieldValue;
6use crate::hash::HashTable;
7
8/// A key that can be used to access field values
9#[derive(Debug, Clone)]
10pub enum FieldKey {
11    /// Access by hash value
12    Hash(u32),
13    /// Access by field name (will be hashed)
14    Name(String),
15}
16
17impl From<u32> for FieldKey {
18    fn from(hash: u32) -> Self {
19        FieldKey::Hash(hash)
20    }
21}
22
23impl From<&str> for FieldKey {
24    fn from(name: &str) -> Self {
25        FieldKey::Name(name.to_string())
26    }
27}
28
29impl From<String> for FieldKey {
30    fn from(name: String) -> Self {
31        FieldKey::Name(name)
32    }
33}
34
35/// An entry (row) in a JMap container
36#[derive(Debug, Clone)]
37pub struct Entry {
38    /// Data stored as hash -> value mappings
39    data: HashMap<u32, FieldValue>,
40}
41
42impl Entry {
43    /// Create a new empty entry
44    pub(crate) fn new() -> Self {
45        Self {
46            data: HashMap::new(),
47        }
48    }
49
50    /// Create an entry with pre-allocated capacity
51    pub(crate) fn with_capacity(capacity: usize) -> Self {
52        Self {
53            data: HashMap::with_capacity(capacity),
54        }
55    }
56
57    /// Get a value by hash
58    pub fn get_by_hash(&self, hash: u32) -> Option<&FieldValue> {
59        self.data.get(&hash)
60    }
61
62    /// Get a value by name, using the provided hash table
63    pub fn get<H: HashTable>(&self, hash_table: &H, name: &str) -> Option<&FieldValue> {
64        let hash = hash_table.calc(name);
65        self.data.get(&hash)
66    }
67
68    /// Get an integer value by hash
69    pub fn get_int_by_hash(&self, hash: u32) -> Option<i32> {
70        self.get_by_hash(hash).and_then(|v| v.as_int())
71    }
72
73    /// Get an integer value by name
74    pub fn get_int<H: HashTable>(&self, hash_table: &H, name: &str) -> Option<i32> {
75        self.get(hash_table, name).and_then(|v| v.as_int())
76    }
77
78    /// Get a float value by hash
79    pub fn get_float_by_hash(&self, hash: u32) -> Option<f32> {
80        self.get_by_hash(hash).and_then(|v| v.as_float())
81    }
82
83    /// Get a float value by name
84    pub fn get_float<H: HashTable>(&self, hash_table: &H, name: &str) -> Option<f32> {
85        self.get(hash_table, name).and_then(|v| v.as_float())
86    }
87
88    /// Get a string value by hash
89    pub fn get_string_by_hash(&self, hash: u32) -> Option<&str> {
90        self.get_by_hash(hash).and_then(|v| v.as_str())
91    }
92
93    /// Get a string value by name
94    pub fn get_string<H: HashTable>(&self, hash_table: &H, name: &str) -> Option<&str> {
95        self.get(hash_table, name).and_then(|v| v.as_str())
96    }
97
98    /// Set a value by hash
99    pub fn set_by_hash(&mut self, hash: u32, value: FieldValue) {
100        self.data.insert(hash, value);
101    }
102
103    /// Set a value by name, using the provided hash table
104    pub fn set<H: HashTable>(&mut self, hash_table: &H, name: &str, value: FieldValue) {
105        let hash = hash_table.calc(name);
106        self.data.insert(hash, value);
107    }
108
109    /// Check if this entry contains a field by hash
110    pub fn contains_hash(&self, hash: u32) -> bool {
111        self.data.contains_key(&hash)
112    }
113
114    /// Check if this entry contains a field by name
115    pub fn contains<H: HashTable>(&self, hash_table: &H, name: &str) -> bool {
116        let hash = hash_table.calc(name);
117        self.data.contains_key(&hash)
118    }
119
120    /// Get the number of fields in this entry
121    pub fn len(&self) -> usize {
122        self.data.len()
123    }
124
125    /// Check if this entry is empty
126    pub fn is_empty(&self) -> bool {
127        self.data.is_empty()
128    }
129
130    /// Iterate over all hash-value pairs
131    pub fn iter(&self) -> impl Iterator<Item = (&u32, &FieldValue)> {
132        self.data.iter()
133    }
134
135    /// Get mutable access to the internal data map
136    pub(crate) fn data_mut(&mut self) -> &mut HashMap<u32, FieldValue> {
137        &mut self.data
138    }
139}
140
141impl Default for Entry {
142    fn default() -> Self {
143        Self::new()
144    }
145}