serde_tagged/util/
mod.rs

1//! Utilities for de-/serialization.
2
3#[cfg(feature = "erased")]
4pub mod erased;
5
6pub(crate) mod de;
7pub(crate) mod ser;
8
9
10use serde;
11use std;
12
13
14/// A type that can be used to as a potentially temporary string-based tag.
15/// 
16/// This type can be constructed (and deserialiezd) from both an owned string
17/// and a borroewd string. While there are similarities to `Cow<str>`, this type
18/// will always be deserialized as `Borrowed` if the deserializer allows this.
19/// Unlike `&'de str`, this type can, however, also be deserialized from an
20/// owned string or a temporary string not fulfilling the required lifetime
21/// bound.
22/// 
23/// The intended use of this type is as a temporary tag store/reference to be
24/// passed on to a string-based `SeedFactory` implementation.
25#[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}