1 //! Structured keys. 2 3 use std::borrow::Borrow; 4 use std::cmp; 5 use std::fmt; 6 use std::hash; 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 { key: self.key } 26 } 27 } 28 29 impl ToKey for str { to_key(&self) -> Key30 fn to_key(&self) -> Key { 31 Key::from_str(self) 32 } 33 } 34 35 /// A key in a structured key-value pair. 36 #[derive(Clone)] 37 pub struct Key<'k> { 38 key: &'k str, 39 } 40 41 impl<'k> Key<'k> { 42 /// Get a key from a borrowed string. from_str(key: &'k str) -> Self43 pub fn from_str(key: &'k str) -> Self { 44 Key { key: key } 45 } 46 47 /// Get a borrowed string from this key. as_str(&self) -> &str48 pub fn as_str(&self) -> &str { 49 self.key 50 } 51 } 52 53 impl<'k> fmt::Debug for Key<'k> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 55 self.key.fmt(f) 56 } 57 } 58 59 impl<'k> fmt::Display for Key<'k> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 61 self.key.fmt(f) 62 } 63 } 64 65 impl<'k> hash::Hash for Key<'k> { hash<H>(&self, state: &mut H) where H: hash::Hasher,66 fn hash<H>(&self, state: &mut H) 67 where 68 H: hash::Hasher, 69 { 70 self.as_str().hash(state) 71 } 72 } 73 74 impl<'k, 'ko> PartialEq<Key<'ko>> for Key<'k> { eq(&self, other: &Key<'ko>) -> bool75 fn eq(&self, other: &Key<'ko>) -> bool { 76 self.as_str().eq(other.as_str()) 77 } 78 } 79 80 impl<'k> Eq for Key<'k> {} 81 82 impl<'k, 'ko> PartialOrd<Key<'ko>> for Key<'k> { partial_cmp(&self, other: &Key<'ko>) -> Option<cmp::Ordering>83 fn partial_cmp(&self, other: &Key<'ko>) -> Option<cmp::Ordering> { 84 self.as_str().partial_cmp(other.as_str()) 85 } 86 } 87 88 impl<'k> Ord for Key<'k> { cmp(&self, other: &Self) -> cmp::Ordering89 fn cmp(&self, other: &Self) -> cmp::Ordering { 90 self.as_str().cmp(other.as_str()) 91 } 92 } 93 94 impl<'k> AsRef<str> for Key<'k> { as_ref(&self) -> &str95 fn as_ref(&self) -> &str { 96 self.as_str() 97 } 98 } 99 100 impl<'k> Borrow<str> for Key<'k> { borrow(&self) -> &str101 fn borrow(&self) -> &str { 102 self.as_str() 103 } 104 } 105 106 impl<'k> From<&'k str> for Key<'k> { from(s: &'k str) -> Self107 fn from(s: &'k str) -> Self { 108 Key::from_str(s) 109 } 110 } 111 112 #[cfg(feature = "std")] 113 mod std_support { 114 use super::*; 115 116 use std::borrow::Cow; 117 118 impl ToKey for String { to_key(&self) -> Key119 fn to_key(&self) -> Key { 120 Key::from_str(self) 121 } 122 } 123 124 impl<'a> ToKey for Cow<'a, str> { to_key(&self) -> Key125 fn to_key(&self) -> Key { 126 Key::from_str(self) 127 } 128 } 129 } 130 131 #[cfg(test)] 132 mod tests { 133 use super::*; 134 135 #[test] key_from_string()136 fn key_from_string() { 137 assert_eq!("a key", Key::from_str("a key").as_str()); 138 } 139 } 140