Skip to content

Commit 7535e94

Browse files
filmorscrogson
andauthored
Implement Hash for atoms (#695)
--------- Co-authored-by: Sonny Scroggin <[email protected]>
1 parent f5e2b09 commit 7535e94

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

rustler/src/types/atom.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::wrapper::atom;
22
use crate::wrapper::NIF_TERM;
33
use crate::{Decoder, Encoder, Env, Error, NifResult, Term};
4+
use std::fmt;
5+
use std::hash::{Hash, Hasher};
46

57
// Atoms are a special case of a term. They can be stored and used on all envs regardless of where
68
// it lives and when it is created.
@@ -81,7 +83,6 @@ impl Atom {
8183
}
8284
}
8385

84-
use std::fmt;
8586
impl fmt::Debug for Atom {
8687
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
8788
crate::wrapper::term::fmt(self.as_c_arg(), f)
@@ -137,6 +138,15 @@ pub(in crate::types) fn decode_bool(term: Term) -> NifResult<bool> {
137138
Err(Error::BadArg)
138139
}
139140

141+
impl Hash for Atom {
142+
fn hash<H: Hasher>(&self, state: &mut H) {
143+
use crate::sys::{enif_hash, ErlNifHash};
144+
let hash =
145+
unsafe { enif_hash(ErlNifHash::ERL_NIF_INTERNAL_HASH, self.as_c_arg(), 0) as u32 };
146+
state.write_u32(hash);
147+
}
148+
}
149+
140150
// This is safe because atoms are never removed/changed once they are created.
141151
unsafe impl Sync for Atom {}
142152
unsafe impl Send for Atom {}

rustler_tests/lib/rustler_test.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ defmodule RustlerTest do
6464
def map_from_arrays(_keys, _values), do: err()
6565
def map_from_pairs(_pairs), do: err()
6666
def map_generic(_), do: err()
67+
def map_atom_keys(_), do: err()
6768

6869
def resource_make(), do: err()
6970
def resource_set_integer_field(_, _), do: err()

rustler_tests/native/rustler_test/src/test_map.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustler::types::map::MapIterator;
22
use rustler::types::tuple::make_tuple;
3-
use rustler::{Encoder, Env, Error, ListIterator, NifResult, Term};
3+
use rustler::{Atom, Encoder, Env, Error, ListIterator, NifResult, Term};
44

55
#[rustler::nif]
66
pub fn sum_map_values(iter: MapIterator) -> NifResult<i64> {
@@ -62,3 +62,10 @@ pub fn map_generic(
6262
) -> std::collections::HashMap<i64, String> {
6363
map
6464
}
65+
66+
#[rustler::nif]
67+
pub fn map_atom_keys(
68+
map: std::collections::HashMap<Atom, String>,
69+
) -> std::collections::HashMap<Atom, String> {
70+
map
71+
}

0 commit comments

Comments
 (0)