1 //! Structured keys. 2 3 use std::fmt; 4 use std::cmp; 5 use std::hash; 6 use std::borrow::Borrow; 7 8 /// A type that can be converted into a [`Key`](struct.Key.html). 9 pub trait ToKey { 10 /// Perform the conversion. to_key(&self) -> Key11 fn to_key(&self) -> Key; 12 } 13 14 impl<'a, T> ToKey for &'a T 15 where 16 T: ToKey + ?Sized, 17 { to_key(&self) -> Key18 fn to_key(&self) -> Key { 19 (**self).to_key() 20 } 21 } 22 23 impl<'k> ToKey for Key<'k> { to_key(&self) -> Key24 fn to_key(&self) -> Key { 25 Key { 26 key: self.key, 27 } 28 } 29 } 30 31 impl ToKey for str { to_key(&self) -> Key32 fn to_key(&self) -> Key { 33 Key::from_str(self) 34 } 35 } 36 37 /// A key in a structured key-value pair. 38 #[derive(Clone)] 39 pub struct Key<'k> { 40 key: &'k str, 41 } 42 43 impl<'k> Key<'k> { 44 /// Get a key from a borrowed string. from_str(key: &'k str) -> Self45 pub fn from_str(key: &'k str) -> Self { 46 Key { 47 key: key, 48 } 49 } 50 51 /// Get a borrowed string from this key. as_str(&self) -> &str52 pub fn as_str(&self) -> &str { 53 self.key 54 } 55 } 56 57 impl<'k> fmt::Debug for Key<'k> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 59 self.key.fmt(f) 60 } 61 } 62 63 impl<'k> fmt::Display for Key<'k> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 65 self.key.fmt(f) 66 } 67 } 68 69 impl<'k> hash::Hash for Key<'k> { hash<H>(&self, state: &mut H) where H: hash::Hasher,70 fn hash<H>(&self, state: &mut H) 71 where 72 H: hash::Hasher, 73 { 74 self.as_str().hash(state) 75 } 76 } 77 78 impl<'k, 'ko> PartialEq<Key<'ko>> for Key<'k> { eq(&self, other: &Key<'ko>) -> bool79 fn eq(&self, other: &Key<'ko>) -> bool { 80 self.as_str().eq(other.as_str()) 81 } 82 } 83 84 impl<'k> Eq for Key<'k> {} 85 86 impl<'k, 'ko> PartialOrd<Key<'ko>> for Key<'k> { partial_cmp(&self, other: &Key<'ko>) -> Option<cmp::Ordering>87 fn partial_cmp(&self, other: &Key<'ko>) -> Option<cmp::Ordering> { 88 self.as_str().partial_cmp(other.as_str()) 89 } 90 } 91 92 impl<'k> Ord for Key<'k> { cmp(&self, other: &Self) -> cmp::Ordering93 fn cmp(&self, other: &Self) -> cmp::Ordering { 94 self.as_str().cmp(other.as_str()) 95 } 96 } 97 98 impl<'k> AsRef<str> for Key<'k> { as_ref(&self) -> &str99 fn as_ref(&self) -> &str { 100 self.as_str() 101 } 102 } 103 104 impl<'k> Borrow<str> for Key<'k> { borrow(&self) -> &str105 fn borrow(&self) -> &str { 106 self.as_str() 107 } 108 } 109 110 impl<'k> From<&'k str> for Key<'k> { from(s: &'k str) -> Self111 fn from(s: &'k str) -> Self { 112 Key::from_str(s) 113 } 114 } 115 116 #[cfg(feature = "std")] 117 mod std_support { 118 use super::*; 119 120 use std::borrow::Cow; 121 122 impl ToKey for String { to_key(&self) -> Key123 fn to_key(&self) -> Key { 124 Key::from_str(self) 125 } 126 } 127 128 impl<'a> ToKey for Cow<'a, str> { to_key(&self) -> Key129 fn to_key(&self) -> Key { 130 Key::from_str(self) 131 } 132 } 133 } 134 135 #[cfg(test)] 136 mod tests { 137 use super::*; 138 139 #[test] key_from_string()140 fn key_from_string() { 141 assert_eq!("a key", Key::from_str("a key").as_str()); 142 } 143 } 144