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