1use crate::MaybeStaticStr;
4use std::borrow::Borrow;
5use std::fmt;
6
7pub trait ToKey {
9 fn to_key(&self) -> Key<'_>;
11}
12
13impl<T> ToKey for &T
14where
15 T: ToKey + ?Sized,
16{
17 fn to_key(&self) -> Key<'_> {
18 (**self).to_key()
19 }
20}
21
22impl<'k> ToKey for Key<'k> {
23 fn to_key(&self) -> Key<'_> {
24 Key { key: self.key }
25 }
26}
27
28impl ToKey for str {
29 fn to_key(&self) -> Key<'_> {
30 Key::from_str(self)
31 }
32}
33
34#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
38pub struct Key<'k> {
39 key: MaybeStaticStr<'k>,
40}
41
42impl<'k> Key<'k> {
43 #[allow(clippy::should_implement_trait)] pub fn from_str(key: &'k str) -> Self {
46 Key {
47 key: MaybeStaticStr::Borrowed(key),
48 }
49 }
50
51 pub fn from_str_static(key: &'static str) -> Self {
53 Key {
54 key: MaybeStaticStr::Static(key),
55 }
56 }
57
58 pub fn as_str(&self) -> &str {
63 self.key.get()
64 }
65
66 pub fn to_borrowed_str(&self) -> Option<&'k str> {
71 Some(self.key.get())
75 }
76
77 pub fn to_static_str(&self) -> Option<&'static str> {
79 match self.key {
80 MaybeStaticStr::Static(s) => Some(s),
81 MaybeStaticStr::Borrowed(_) => None,
82 }
83 }
84}
85
86impl<'k> fmt::Display for Key<'k> {
87 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88 self.key.get().fmt(f)
89 }
90}
91
92impl<'k> AsRef<str> for Key<'k> {
93 fn as_ref(&self) -> &str {
94 self.as_str()
95 }
96}
97
98impl<'k> Borrow<str> for Key<'k> {
99 fn borrow(&self) -> &str {
100 self.as_str()
101 }
102}
103
104impl<'k> From<&'k str> for Key<'k> {
105 fn from(s: &'k str) -> Self {
106 Key::from_str(s)
107 }
108}
109
110#[cfg(feature = "std")]
111mod std_support {
112 use super::*;
113
114 use std::borrow::Cow;
115
116 impl ToKey for String {
117 fn to_key(&self) -> Key<'_> {
118 Key::from_str(self)
119 }
120 }
121
122 impl<'a> ToKey for Cow<'a, str> {
123 fn to_key(&self) -> Key<'_> {
124 Key::from_str(self)
125 }
126 }
127}
128
129#[cfg(feature = "kv_sval")]
130mod sval_support {
131 use super::*;
132
133 use sval::Value;
134 use sval_ref::ValueRef;
135
136 impl<'a> Value for Key<'a> {
137 fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(
138 &'sval self,
139 stream: &mut S,
140 ) -> sval::Result {
141 self.key.get().stream(stream)
142 }
143 }
144
145 impl<'a> ValueRef<'a> for Key<'a> {
146 fn stream_ref<S: sval::Stream<'a> + ?Sized>(&self, stream: &mut S) -> sval::Result {
147 self.key.get().stream(stream)
148 }
149 }
150}
151
152#[cfg(feature = "kv_serde")]
153mod serde_support {
154 use super::*;
155
156 use serde_core::{Serialize, Serializer};
157
158 impl<'a> Serialize for Key<'a> {
159 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
160 where
161 S: Serializer,
162 {
163 self.key.get().serialize(serializer)
164 }
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171
172 #[test]
173 fn key_from_string() {
174 assert_eq!("a key", Key::from_str("a key").as_str());
175 }
176
177 #[test]
178 fn key_to_borrowed() {
179 assert_eq!("a key", Key::from_str("a key").to_borrowed_str().unwrap());
180 }
181}