1use std::borrow::Borrow;
2use std::str::FromStr;
3
4/// Opaque string storage internal to `toml_edit`
5#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct InternalString(Inner);
7
8#[cfg(feature = "kstring")]
9type Inner = kstring::KString;
10#[cfg(not(feature = "kstring"))]
11type Inner = String;
12
13impl InternalString {
14 /// Create an empty string
15 pub fn new() -> Self {
16 InternalString(Inner::new())
17 }
18
19 /// Access the underlying string
20 #[inline]
21 pub fn as_str(&self) -> &str {
22 self.0.as_str()
23 }
24}
25
26impl std::fmt::Debug for InternalString {
27 #[inline]
28 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
29 self.0.fmt(formatter)
30 }
31}
32
33impl std::ops::Deref for InternalString {
34 type Target = str;
35
36 #[inline]
37 fn deref(&self) -> &str {
38 self.as_str()
39 }
40}
41
42impl Borrow<str> for InternalString {
43 #[inline]
44 fn borrow(&self) -> &str {
45 self.as_str()
46 }
47}
48
49impl AsRef<str> for InternalString {
50 #[inline]
51 fn as_ref(&self) -> &str {
52 self.as_str()
53 }
54}
55
56impl From<&str> for InternalString {
57 #[inline]
58 fn from(s: &str) -> Self {
59 #[cfg(feature = "kstring")]
60 let inner = kstring::KString::from_ref(s);
61 #[cfg(not(feature = "kstring"))]
62 let inner: String = String::from(s);
63
64 InternalString(inner)
65 }
66}
67
68impl From<String> for InternalString {
69 #[inline]
70 fn from(s: String) -> Self {
71 #[allow(clippy::useless_conversion)] // handle any string type
72 InternalString(s.into())
73 }
74}
75
76impl From<&String> for InternalString {
77 #[inline]
78 fn from(s: &String) -> Self {
79 InternalString(s.into())
80 }
81}
82
83impl From<&InternalString> for InternalString {
84 #[inline]
85 fn from(s: &InternalString) -> Self {
86 s.clone()
87 }
88}
89
90impl From<Box<str>> for InternalString {
91 #[inline]
92 fn from(s: Box<str>) -> Self {
93 InternalString(s.into())
94 }
95}
96
97impl FromStr for InternalString {
98 type Err = core::convert::Infallible;
99 #[inline]
100 fn from_str(s: &str) -> Result<Self, Self::Err> {
101 Ok(Self::from(s))
102 }
103}
104
105impl std::fmt::Display for InternalString {
106 #[inline]
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 self.as_str().fmt(f)
109 }
110}
111
112#[cfg(feature = "serde")]
113impl serde::Serialize for InternalString {
114 #[inline]
115 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
116 where
117 S: serde::Serializer,
118 {
119 serializer.serialize_str(self.as_str())
120 }
121}
122
123#[cfg(feature = "serde")]
124impl<'de> serde::Deserialize<'de> for InternalString {
125 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
126 where
127 D: serde::Deserializer<'de>,
128 {
129 deserializer.deserialize_string(StringVisitor)
130 }
131}
132
133#[cfg(feature = "serde")]
134struct StringVisitor;
135
136#[cfg(feature = "serde")]
137impl<'de> serde::de::Visitor<'de> for StringVisitor {
138 type Value = InternalString;
139
140 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141 formatter.write_str("a string")
142 }
143
144 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
145 where
146 E: serde::de::Error,
147 {
148 Ok(InternalString::from(v))
149 }
150
151 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
152 where
153 E: serde::de::Error,
154 {
155 Ok(InternalString::from(v))
156 }
157
158 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
159 where
160 E: serde::de::Error,
161 {
162 match std::str::from_utf8(v) {
163 Ok(s) => Ok(InternalString::from(s)),
164 Err(_) => Err(serde::de::Error::invalid_value(
165 serde::de::Unexpected::Bytes(v),
166 &self,
167 )),
168 }
169 }
170
171 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
172 where
173 E: serde::de::Error,
174 {
175 match String::from_utf8(v) {
176 Ok(s) => Ok(InternalString::from(s)),
177 Err(e) => Err(serde::de::Error::invalid_value(
178 serde::de::Unexpected::Bytes(&e.into_bytes()),
179 &self,
180 )),
181 }
182 }
183}
184