1use std::borrow::Cow;
2use std::fmt::{self, Display, Formatter};
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
9#[cfg_attr(any(test, feature = "proptest"), derive(proptest_derive::Arbitrary))]
10#[serde(transparent)]
11pub struct KeyString(String);
12
13impl KeyString {
14 #[inline]
16 #[must_use]
17 pub fn into_bytes(self) -> Box<[u8]> {
18 self.0.into_bytes().into()
19 }
20
21 #[inline]
23 #[must_use]
24 pub fn is_empty(&self) -> bool {
25 self.0.is_empty()
26 }
27
28 #[inline]
30 #[must_use]
31 pub fn len(&self) -> usize {
32 self.0.len()
33 }
34
35 #[inline]
37 #[must_use]
38 pub fn as_str(&self) -> &str {
39 &self.0
40 }
41}
42
43impl Display for KeyString {
44 fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
45 self.0.fmt(fmt)
46 }
47}
48
49impl AsRef<str> for KeyString {
50 fn as_ref(&self) -> &str {
51 &self.0
52 }
53}
54
55impl std::ops::Deref for KeyString {
56 type Target = str;
57 fn deref(&self) -> &str {
58 &self.0
59 }
60}
61
62impl std::borrow::Borrow<str> for KeyString {
63 fn borrow(&self) -> &str {
64 &self.0
65 }
66}
67
68impl PartialEq<str> for KeyString {
69 fn eq(&self, that: &str) -> bool {
70 self.0[..].eq(that)
71 }
72}
73
74impl From<&str> for KeyString {
75 fn from(s: &str) -> Self {
76 Self(s.into())
77 }
78}
79
80impl From<String> for KeyString {
81 fn from(s: String) -> Self {
82 Self(s)
83 }
84}
85
86impl From<Cow<'_, str>> for KeyString {
87 fn from(s: Cow<'_, str>) -> Self {
88 Self(s.into())
89 }
90}
91
92impl From<KeyString> for String {
93 fn from(s: KeyString) -> Self {
94 s.0
95 }
96}
97
98#[cfg(any(test, feature = "arbitrary"))]
99impl quickcheck::Arbitrary for KeyString {
100 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
101 String::arbitrary(g).into()
102 }
103
104 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
105 let s = self.0.clone();
106 Box::new(s.shrink().map(Into::into))
107 }
108}
109
110#[cfg(any(test, feature = "lua"))]
111mod lua {
112 use mlua::prelude::LuaResult;
113 use mlua::{FromLua, IntoLua, Lua, Value as LuaValue};
114
115 use super::KeyString;
116
117 impl FromLua for KeyString {
118 fn from_lua(value: LuaValue, lua: &Lua) -> LuaResult<Self> {
119 String::from_lua(value, lua).map(Self::from)
120 }
121 }
122
123 impl IntoLua for KeyString {
124 fn into_lua(self, lua: &Lua) -> LuaResult<LuaValue> {
125 self.0.into_lua(lua)
126 }
127 }
128}