I'm trying to port a codebase from C to Rust. Type casting is very implicit and manually trying to control memory makes it very difficult to figure out the best solution. The data structure I am trying to port implements a hashtable:
// An entry in the hash table
typedef struct DataEntryStruct
{
char *key;
int data;
struct DataEntryStruct *next;
} DataEntry;
typedef struct DataEntryStruct *HashTable;
// Hash a string to an integer
unsigned int gethash(char *str)
{
unsigned int hash = 5381;
unsigned int retHash;
int c;
while ((c = *str++))
{
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
retHash = hash % HASHTABLEMAXSIZE;
return retHash;
}
// Produce a duplicate string
char *dupstr(const char *s)
{
size_t size = strlen(s) + 1;
char *p = malloc(size);
if (p) memcpy(p, s, size);
return p;
}
// Create a hash table
HashTable *hashtable_create()
{
int i;
HashTable *ht = (HashTable *) calloc(HASHTABLEMAXSIZE, sizeof(HashTable));
if (ht != NULL)
{
for (i = 0; i < HASHTABLEMAXSIZE; i++) ht[i] = NULL;
}
return ht;
}
I think I have figured out how to implement the first blocks, but not the last one with memory allocation:
struct DataEntry {
key: &str,
data: u32,
next: Option<&mut HashTable>,
}
let HashTable = &mut DataEntry;
// get hash for a string
fn gethash(val: &str) -> u32 {
let mut hash: u32 = 5381;
for c in val.chars() {
hash = (hash << 5 as u32).wrapping_add(hash).wrapping_add(c as u32);
}
return hash % HASHTABLEMAXSIZE;
}
// Produce a duplcate string
fn dupstr(val: &str) -> &str {
// only use rust .clone func
val.clone()
}
How do I implement hashtable_create
while being as true as I can to the source?