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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
//! Author --- daniel.bechaz@gmail.com //! Last Moddified --- 2018/03/13 use super::*; /// Derives an `identifier` from a value. /// /// `DeriveIdent` is a "quality of life" trait when using [`WithIdent`](./struct.WithIdent.html). /// /// Any type `T` which implements this trait can easily be converted into a /// `WithIdent<T, I>` instance using `From` and `Into`. pub trait DeriveIdent<I: Eq> { /// Returns an `Identifier` value derived from the passed `value`. /// /// Note: this is an associated function, which means that you have to call it as /// `DeriveIdent::derive_ident(value)` instead of `value.derive_ident()`. This is so /// that there is no conflict with a method on the inner type. /// /// # Examples /// /// ```rust /// # extern crate ident; /// # use ident::*; /// # fn main() { /// assert_eq!(5, DeriveIdent::derive_ident(&5)); //Integer types return themselves by default. /// /// let wi = WithIdent::from(5); /// assert_eq!(wi.get_identifier(), &5); /// assert_eq!(*wi, 5); /// # } /// ``` fn derive_ident(value: &Self) -> I; } impl<T: DeriveIdent<I>, I: Eq> From<T> for WithIdent<T, I> { fn from(from: T) -> Self { Self::new(DeriveIdent::derive_ident(&from), from) } } /// In some cases, such as `integer` types, a value is its own unique `identifier`. /// /// This macro implements [`DeriveIdent`](./trait.DeriveIdent.html) for the passed type to /// simply return itself. (NOTE: the type must derive `Clone`) #[macro_export] macro_rules! impl_identity { ($type:ty) => { impl DeriveIdent<$type> for $type { fn derive_ident(value: &Self) -> $type { value.clone() } } }; ($type:tt $($t:tt)*) => { impl_identity!($type); impl_identity!($($t)*); }; } impl_identity! { usize isize u8 i8 u16 i16 u32 i32 u64 i64 } /// A hash is often a useful and convenient `identifier` value. /// /// This macro implements [`DeriveIdent<u64>`](./trait.DeriveIdent.html) for the passed /// type using the passed [`Hasher`](https://doc.rust-lang.org/std/hash/trait.Hasher.html). /// (NOTE: the type must derive [`Hash`](https://doc.rust-lang.org/std/hash/trait.Hash.html)) /// /// # Examples /// /// ```rust /// #[macro_use] /// extern crate ident; /// /// use std::collections::hash_map::DefaultHasher; /// use ident::*; /// /// #[derive(Hash)] /// struct MyType(pub usize); /// /// //Implements DeriveIdent<u64> for MyType using DefaultHasher to calculate the hash. /// impl_hash_identity!(MyType, DefaultHasher); /// /// fn main() { /// let x = MyType(5); /// println!("{}", DeriveIdent::<u64>::derive_ident(&x)); /// } /// ``` #[macro_export] macro_rules! impl_hash_identity { (($type:tt, $hasher:tt)) => { impl DeriveIdent<u64> for $type { fn derive_ident(value: &Self) -> u64 { use std::hash::{Hash, Hasher}; let mut hasher = $hasher::default(); value.hash(&mut hasher); hasher.finish() } } }; (($type:tt, $hasher:tt) $($t:tt)*) => { impl_hash_identity!(($type, $hasher)); impl_hash_identity!($($t)*); }; ($type:tt, $hasher:tt) => (impl_hash_identity!(($type, $hasher));); }