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(feature = "kv_unstable_sval")]
132 mod sval_support {
133     use super::*;
134 
135     extern crate sval;
136 
137     use self::sval::value::{self, Value};
138 
139     impl<'a> Value for Key<'a> {
stream(&self, stream: &mut value::Stream) -> value::Result140         fn stream(&self, stream: &mut value::Stream) -> value::Result {
141             self.key.stream(stream)
142         }
143     }
144 }
145 
146 #[cfg(feature = "kv_unstable_serde")]
147 mod serde_support {
148     use super::*;
149 
150     extern crate serde;
151 
152     use self::serde::{Serialize, Serializer};
153 
154     impl<'a> Serialize for Key<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,155         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
156         where
157             S: Serializer,
158         {
159             self.key.serialize(serializer)
160         }
161     }
162 }
163 
164 #[cfg(test)]
165 mod tests {
166     use super::*;
167 
168     #[test]
key_from_string()169     fn key_from_string() {
170         assert_eq!("a key", Key::from_str("a key").as_str());
171     }
172 }
173