cop/
symbol.rs

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