1 //! Structured keys.
2 
3 use std::borrow::Borrow;
4 use std::fmt;
5 
6 /// A type that can be converted into a [`Key`](struct.Key.html).
7 pub trait ToKey {
8     /// Perform the conversion.
to_key(&self) -> Key9     fn to_key(&self) -> Key;
10 }
11 
12 impl<'a, T> ToKey for &'a T
13 where
14     T: ToKey + ?Sized,
15 {
to_key(&self) -> Key16     fn to_key(&self) -> Key {
17         (**self).to_key()
18     }
19 }
20 
21 impl<'k> ToKey for Key<'k> {
to_key(&self) -> Key22     fn to_key(&self) -> Key {
23         Key { key: self.key }
24     }
25 }
26 
27 impl ToKey for str {
to_key(&self) -> Key28     fn to_key(&self) -> Key {
29         Key::from_str(self)
30     }
31 }
32 
33 /// A key in a key-value.
34 // These impls must only be based on the as_str() representation of the key
35 // If a new field (such as an optional index) is added to the key they must not affect comparison
36 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
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 }
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::Display 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> AsRef<str> for Key<'k> {
as_ref(&self) -> &str60     fn as_ref(&self) -> &str {
61         self.as_str()
62     }
63 }
64 
65 impl<'k> Borrow<str> for Key<'k> {
borrow(&self) -> &str66     fn borrow(&self) -> &str {
67         self.as_str()
68     }
69 }
70 
71 impl<'k> From<&'k str> for Key<'k> {
from(s: &'k str) -> Self72     fn from(s: &'k str) -> Self {
73         Key::from_str(s)
74     }
75 }
76 
77 #[cfg(feature = "std")]
78 mod std_support {
79     use super::*;
80 
81     use std::borrow::Cow;
82 
83     impl ToKey for String {
to_key(&self) -> Key84         fn to_key(&self) -> Key {
85             Key::from_str(self)
86         }
87     }
88 
89     impl<'a> ToKey for Cow<'a, str> {
to_key(&self) -> Key90         fn to_key(&self) -> Key {
91             Key::from_str(self)
92         }
93     }
94 }
95 
96 #[cfg(feature = "kv_sval")]
97 mod sval_support {
98     use super::*;
99 
100     use sval::Value;
101     use sval_ref::ValueRef;
102 
103     impl<'a> Value for Key<'a> {
stream<'sval, S: sval::Stream<'sval> + ?Sized>( &'sval self, stream: &mut S, ) -> sval::Result104         fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(
105             &'sval self,
106             stream: &mut S,
107         ) -> sval::Result {
108             self.key.stream(stream)
109         }
110     }
111 
112     impl<'a> ValueRef<'a> for Key<'a> {
stream_ref<S: sval::Stream<'a> + ?Sized>(&self, stream: &mut S) -> sval::Result113         fn stream_ref<S: sval::Stream<'a> + ?Sized>(&self, stream: &mut S) -> sval::Result {
114             self.key.stream(stream)
115         }
116     }
117 }
118 
119 #[cfg(feature = "kv_serde")]
120 mod serde_support {
121     use super::*;
122 
123     use serde::{Serialize, Serializer};
124 
125     impl<'a> Serialize for Key<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,126         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
127         where
128             S: Serializer,
129         {
130             self.key.serialize(serializer)
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