• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     // NOTE: This may become `Cow<'k, str>`
39     key: &'k str,
40 }
41 
42 impl<'k> Key<'k> {
43     /// Get a key from a borrowed string.
from_str(key: &'k str) -> Self44     pub fn from_str(key: &'k str) -> Self {
45         Key { key }
46     }
47 
48     /// Get a borrowed string from this key.
49     ///
50     /// The lifetime of the returned string is bound to the borrow of `self` rather
51     /// than to `'k`.
as_str(&self) -> &str52     pub fn as_str(&self) -> &str {
53         self.key
54     }
55 
56     /// Try get a borrowed string for the lifetime `'k` from this key.
57     ///
58     /// If the key is a borrow of a longer lived string, this method will return `Some`.
59     /// If the key is internally buffered, this method will return `None`.
to_borrowed_str(&self) -> Option<&'k str>60     pub fn to_borrowed_str(&self) -> Option<&'k str> {
61         // NOTE: If the internals of `Key` support buffering this
62         // won't be unconditionally `Some` anymore. We want to keep
63         // this option open
64         Some(self.key)
65     }
66 }
67 
68 impl<'k> fmt::Display for Key<'k> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result69     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70         self.key.fmt(f)
71     }
72 }
73 
74 impl<'k> AsRef<str> for Key<'k> {
as_ref(&self) -> &str75     fn as_ref(&self) -> &str {
76         self.as_str()
77     }
78 }
79 
80 impl<'k> Borrow<str> for Key<'k> {
borrow(&self) -> &str81     fn borrow(&self) -> &str {
82         self.as_str()
83     }
84 }
85 
86 impl<'k> From<&'k str> for Key<'k> {
from(s: &'k str) -> Self87     fn from(s: &'k str) -> Self {
88         Key::from_str(s)
89     }
90 }
91 
92 #[cfg(feature = "std")]
93 mod std_support {
94     use super::*;
95 
96     use std::borrow::Cow;
97 
98     impl ToKey for String {
to_key(&self) -> Key99         fn to_key(&self) -> Key {
100             Key::from_str(self)
101         }
102     }
103 
104     impl<'a> ToKey for Cow<'a, str> {
to_key(&self) -> Key105         fn to_key(&self) -> Key {
106             Key::from_str(self)
107         }
108     }
109 }
110 
111 #[cfg(feature = "kv_sval")]
112 mod sval_support {
113     use super::*;
114 
115     use sval::Value;
116     use sval_ref::ValueRef;
117 
118     impl<'a> Value for Key<'a> {
stream<'sval, S: sval::Stream<'sval> + ?Sized>( &'sval self, stream: &mut S, ) -> sval::Result119         fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(
120             &'sval self,
121             stream: &mut S,
122         ) -> sval::Result {
123             self.key.stream(stream)
124         }
125     }
126 
127     impl<'a> ValueRef<'a> for Key<'a> {
stream_ref<S: sval::Stream<'a> + ?Sized>(&self, stream: &mut S) -> sval::Result128         fn stream_ref<S: sval::Stream<'a> + ?Sized>(&self, stream: &mut S) -> sval::Result {
129             self.key.stream(stream)
130         }
131     }
132 }
133 
134 #[cfg(feature = "kv_serde")]
135 mod serde_support {
136     use super::*;
137 
138     use serde::{Serialize, Serializer};
139 
140     impl<'a> Serialize for Key<'a> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,141         fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
142         where
143             S: Serializer,
144         {
145             self.key.serialize(serializer)
146         }
147     }
148 }
149 
150 #[cfg(test)]
151 mod tests {
152     use super::*;
153 
154     #[test]
key_from_string()155     fn key_from_string() {
156         assert_eq!("a key", Key::from_str("a key").as_str());
157     }
158 
159     #[test]
key_to_borrowed()160     fn key_to_borrowed() {
161         assert_eq!("a key", Key::from_str("a key").to_borrowed_str().unwrap());
162     }
163 }
164