diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 3aa2a44..1f2be87 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -290,6 +290,12 @@ fn test_from_string() { assert!(Atom::from("camembert".to_owned()) == Atom::from("camembert")); } +#[test] +fn test_try_static() { + assert!(Atom::try_static("head").is_some()); + assert!(Atom::try_static("not in the static table").is_none()); +} + #[cfg(all(test, feature = "unstable"))] #[path = "bench.rs"] mod bench; diff --git a/src/atom.rs b/src/atom.rs index 5011d40..6da0044 100644 --- a/src/atom.rs +++ b/src/atom.rs @@ -149,6 +149,22 @@ impl Atom { _ => unsafe { debug_unreachable!() }, } } + + pub fn try_static(string_to_add: &str) -> Option { + Self::try_static_internal(string_to_add).ok() + } + + fn try_static_internal(string_to_add: &str) -> Result { + let static_set = Static::get(); + let hash = phf_shared::hash(&*string_to_add, &static_set.key); + let index = phf_shared::get_index(&hash, static_set.disps, static_set.atoms.len()); + + if static_set.atoms[index as usize] == string_to_add { + Ok(Self::pack_static(index)) + } else { + Err(hash) + } + } } impl Default for Atom { @@ -170,13 +186,7 @@ impl Hash for Atom { impl<'a, Static: StaticAtomSet> From> for Atom { fn from(string_to_add: Cow<'a, str>) -> Self { - let static_set = Static::get(); - let hash = phf_shared::hash(&*string_to_add, &static_set.key); - let index = phf_shared::get_index(&hash, static_set.disps, static_set.atoms.len()); - - if static_set.atoms[index as usize] == string_to_add { - Self::pack_static(index) - } else { + Self::try_static_internal(&*string_to_add).unwrap_or_else(|hash| { let len = string_to_add.len(); if len <= MAX_INLINE_LEN { let mut data: u64 = (INLINE_TAG as u64) | ((len as u64) << LEN_OFFSET); @@ -200,7 +210,7 @@ impl<'a, Static: StaticAtomSet> From> for Atom { phantom: PhantomData, } } - } + }) } }