1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
//! Shared strings with fast copying, hashing and equality checking.
use core::fmt;
use core::hash::{Hash, Hasher};
/// Shared string with fast cloning, hashing, and equality check.
///
/// Cloning, hashing, and equality checking is performed on
/// the address of the pointer, making them constant-time operations.
///
/// Note that two different symbols pointing to equivalent strings
/// are not equal, as well as their hashes:
///
/// ~~~
/// # use cop::Symbol;
/// # use std::collections::hash_map::DefaultHasher;
/// # use std::hash::{Hash, Hasher};
/// let h1 = String::from("Hello");
/// let h2 = String::from("Hello");
/// let wl = String::from("World");
/// let s1 = Symbol::new(&h1);
/// let s2 = Symbol::new(&h2);
/// let s3 = Symbol::new(&wl);
///
/// assert_eq!(s1, s1);
/// assert_eq!(s1, s1.clone());
/// assert_ne!(s1, s2);
/// assert_ne!(s1, s3);
///
/// let hash = |s: Symbol| -> u64 {
/// let mut hasher = DefaultHasher::new();
/// s.hash(&mut hasher);
/// hasher.finish()
/// };
///
/// assert_eq!(hash(s1), hash(s1.clone()));
/// assert_ne!(hash(s1), hash(s2));
/// ~~~
#[derive(Copy, Clone, Debug)]
pub struct Symbol<'s>(&'s str);
impl<'s> Symbol<'s> {
/// Create a new symbol with given name.
pub fn new(s: &'s str) -> Self {
Self(s)
}
}
impl<'s> Hash for Symbol<'s> {
fn hash<H: Hasher>(&self, state: &mut H) {
core::ptr::hash(self.0, state)
}
}
impl<'s> PartialEq for Symbol<'s> {
fn eq(&self, other: &Self) -> bool {
core::ptr::eq(self.0, other.0)
}
}
impl<'s> Eq for Symbol<'s> {}
impl<'s> fmt::Display for Symbol<'s> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}