1#[cfg(feature = "erased")]
4pub mod erased;
5
6pub(crate) mod de;
7pub(crate) mod ser;
8
9
10use serde;
11use std;
12
13
14#[derive(Clone, Debug)]
26pub enum TagString<'a> {
27 Owned(String),
28 Borrowed(&'a str),
29}
30
31impl<'a> From<&'a str> for TagString<'a> {
32 fn from(source: &'a str) -> Self {
33 TagString::Borrowed(source)
34 }
35}
36
37impl<'a> From<String> for TagString<'a> {
38 fn from(source: String) -> Self {
39 TagString::Owned(source)
40 }
41}
42
43impl<'a> From<std::borrow::Cow<'a, str>> for TagString<'a> {
44 fn from(source: std::borrow::Cow<'a, str>) -> Self {
45 match source {
46 std::borrow::Cow::Owned(v) => TagString::Owned(v),
47 std::borrow::Cow::Borrowed(v) => TagString::Borrowed(v),
48 }
49 }
50}
51
52impl<'a> From<TagString<'a>> for std::borrow::Cow<'a, str> {
53 fn from(val: TagString<'a>) -> Self {
54 match val {
55 TagString::Owned(v) => std::borrow::Cow::Owned(v),
56 TagString::Borrowed(v) => std::borrow::Cow::Borrowed(v),
57 }
58 }
59}
60
61impl<'a> std::ops::Deref for TagString<'a> {
62 type Target = str;
63
64 fn deref(&self) -> &Self::Target {
65 match *self {
66 TagString::Owned(ref v) => v,
67 TagString::Borrowed(v) => v,
68 }
69 }
70}
71
72impl<'a, B> std::cmp::PartialEq<B> for TagString<'a>
73where
74 B: PartialEq<str>,
75{
76 fn eq(&self, other: &B) -> bool {
77 other.eq(&**self)
78 }
79}
80
81impl<'a, 'b> std::cmp::PartialEq<TagString<'b>> for TagString<'a> {
82 fn eq(&self, other: &TagString<'b>) -> bool {
83 (**self).eq(&**other)
84 }
85}
86
87impl<'a> std::cmp::Eq for TagString<'a> {}
88
89impl<'a, B> std::cmp::PartialOrd<B> for TagString<'a>
90where
91 B: PartialOrd<str>,
92{
93 fn partial_cmp(&self, other: &B) -> Option<std::cmp::Ordering> {
94 other.partial_cmp(&**self).map(std::cmp::Ordering::reverse)
95 }
96}
97
98impl<'a, 'b> std::cmp::PartialOrd<TagString<'b>> for TagString<'a> {
99 fn partial_cmp(&self, other: &TagString) -> Option<std::cmp::Ordering> {
100 (**self).partial_cmp(&**other)
101 }
102}
103
104impl<'a> std::cmp::Ord for TagString<'a> {
105 fn cmp(&self, other: &TagString) -> std::cmp::Ordering {
106 (**self).cmp(&**other)
107 }
108}
109
110impl<'a> std::fmt::Display for TagString<'a> {
111 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
112 (**self).fmt(f)
113 }
114}
115
116impl<'a> std::hash::Hash for TagString<'a> {
117 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
118 (**self).hash(state)
119 }
120}
121
122impl<'a> AsRef<str> for TagString<'a> {
123 fn as_ref(&self) -> &str {
124 self
125 }
126}
127
128
129impl<'de> serde::Deserialize<'de> for TagString<'de> {
130 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
131 where
132 D: serde::Deserializer<'de>,
133 {
134 struct Visitor;
135
136 impl<'de> serde::de::Visitor<'de> for Visitor {
137 type Value = TagString<'de>;
138
139 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
140 write!(formatter, "any type of string")
141 }
142
143 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
144 where
145 E: serde::de::Error,
146 {
147 Ok(TagString::Owned(v.to_owned()))
148 }
149
150 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
151 where
152 E: serde::de::Error,
153 {
154 Ok(TagString::Borrowed(v))
155 }
156
157 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
158 where
159 E: serde::de::Error,
160 {
161 Ok(TagString::Owned(v))
162 }
163 }
164
165 deserializer.deserialize_str(Visitor)
166 }
167}
168
169impl<'a> serde::Serialize for TagString<'a> {
170 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
171 where
172 S: serde::Serializer
173 {
174 serializer.serialize_str(self)
175 }
176}