1use core::str;
28
29use crate::Result;
30
31#[derive(Copy, Clone)]
32pub struct Owned(());
33
34impl crate::traits::Owned for Owned {
35 type Reader<'a> = Reader<'a>;
36 type Builder<'a> = Builder<'a>;
37}
38
39impl crate::introspect::Introspect for Owned {
40 fn introspect() -> crate::introspect::Type {
41 crate::introspect::TypeVariant::Text.into()
42 }
43}
44
45#[derive(Copy, Clone, PartialEq, PartialOrd)]
49pub struct Reader<'a>(pub &'a [u8]);
50
51impl<'a> core::cmp::PartialEq<&'a str> for Reader<'a> {
52 #[inline]
53 fn eq(&self, other: &&'a str) -> bool {
54 self.as_bytes() == other.as_bytes()
55 }
56}
57
58impl<'a> core::cmp::PartialEq<Reader<'a>> for &'a str {
59 #[inline]
60 fn eq(&self, other: &Reader<'a>) -> bool {
61 self.as_bytes() == other.as_bytes()
62 }
63}
64
65#[cfg(feature = "alloc")]
66impl core::cmp::PartialEq<alloc::string::String> for Reader<'_> {
67 #[inline]
68 fn eq(&self, other: &alloc::string::String) -> bool {
69 self.as_bytes() == other.as_bytes()
70 }
71}
72
73#[cfg(feature = "alloc")]
74impl<'a> core::cmp::PartialEq<Reader<'a>> for alloc::string::String {
75 #[inline]
76 fn eq(&self, other: &Reader<'a>) -> bool {
77 self.as_bytes() == other.as_bytes()
78 }
79}
80
81impl<'a> core::cmp::PartialOrd<&'a str> for Reader<'a> {
82 #[inline]
83 fn partial_cmp(&self, other: &&'a str) -> Option<core::cmp::Ordering> {
84 self.as_bytes().partial_cmp(other.as_bytes())
85 }
86}
87
88impl<'a> core::cmp::PartialOrd<Reader<'a>> for &'a str {
89 #[inline]
90 fn partial_cmp(&self, other: &Reader<'a>) -> Option<core::cmp::Ordering> {
91 self.as_bytes().partial_cmp(other.as_bytes())
92 }
93}
94
95impl core::fmt::Debug for Reader<'_> {
96 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
97 match self.to_str() {
98 Ok(s) => write!(f, "{s:?}"),
99 Err(_) => write!(f, "<invalid utf-8: {:?}>", self.as_bytes()),
100 }
101 }
102}
103
104impl<'a> From<&'a str> for Reader<'a> {
105 #[inline]
106 fn from(value: &'a str) -> Self {
107 Self(value.as_bytes())
108 }
109}
110
111impl<'a> From<&'a [u8]> for Reader<'a> {
112 #[inline]
113 fn from(value: &'a [u8]) -> Self {
114 Self(value)
115 }
116}
117
118impl<'a, const N: usize> From<&'a [u8; N]> for Reader<'a> {
119 fn from(value: &'a [u8; N]) -> Self {
120 Self(&value[..])
121 }
122}
123
124impl<'a> TryFrom<Reader<'a>> for &'a str {
125 type Error = core::str::Utf8Error;
126 fn try_from(value: Reader<'a>) -> core::result::Result<&'a str, core::str::Utf8Error> {
127 let Reader(v) = value;
128 str::from_utf8(v)
129 }
130}
131
132impl<'a> crate::traits::FromPointerReader<'a> for Reader<'a> {
133 fn get_from_pointer(
134 reader: &crate::private::layout::PointerReader<'a>,
135 default: Option<&'a [crate::Word]>,
136 ) -> Result<Reader<'a>> {
137 reader.get_text(default)
138 }
139}
140
141impl<'a> Reader<'a> {
142 #[inline]
144 pub fn len(&self) -> usize {
145 self.as_bytes().len()
146 }
147
148 #[inline]
149 pub fn is_empty(&self) -> bool {
150 self.len() == 0
151 }
152
153 #[inline]
154 pub fn as_bytes(self) -> &'a [u8] {
155 let Self(d) = self;
156 d
157 }
158
159 #[inline]
161 pub fn to_str(self) -> core::result::Result<&'a str, core::str::Utf8Error> {
162 let Self(s) = self;
163 str::from_utf8(s)
164 }
165
166 #[cfg(feature = "alloc")]
167 #[inline]
169 pub fn to_string(self) -> core::result::Result<alloc::string::String, core::str::Utf8Error> {
170 Ok(self.to_str()?.into())
171 }
172}
173
174pub struct Builder<'a> {
175 bytes: &'a mut [u8],
177
178 pos: usize,
180}
181
182impl core::cmp::PartialEq for Builder<'_> {
183 fn eq(&self, other: &Self) -> bool {
184 self.bytes == other.bytes
185 }
186}
187
188impl<'a> core::cmp::PartialEq<&'a str> for Builder<'a> {
189 fn eq(&self, other: &&'a str) -> bool {
190 self.bytes == other.as_bytes()
191 }
192}
193
194impl<'a> core::cmp::PartialEq<Builder<'a>> for &'a str {
195 fn eq(&self, other: &Builder<'a>) -> bool {
196 self.as_bytes() == other.bytes
197 }
198}
199
200impl<'a> Builder<'a> {
201 #[inline]
202 pub fn new(bytes: &mut [u8]) -> Builder<'_> {
203 Builder { bytes, pos: 0 }
204 }
205
206 #[inline]
207 pub fn with_pos(bytes: &mut [u8], pos: usize) -> Builder<'_> {
208 Builder { bytes, pos }
209 }
210
211 #[inline]
213 pub fn len(&self) -> usize {
214 self.bytes.len()
215 }
216
217 #[inline]
218 pub fn is_empty(&self) -> bool {
219 self.len() == 0
220 }
221
222 #[inline]
223 pub fn as_bytes(self) -> &'a [u8] {
224 self.bytes
225 }
226
227 #[inline]
229 pub fn to_str(self) -> core::result::Result<&'a str, core::str::Utf8Error> {
230 str::from_utf8(self.bytes)
231 }
232
233 #[cfg(feature = "alloc")]
234 #[inline]
236 pub fn to_string(self) -> core::result::Result<alloc::string::String, core::str::Utf8Error> {
237 Ok(self.to_str()?.into())
238 }
239
240 #[inline]
241 pub fn as_bytes_mut(self) -> &'a mut [u8] {
242 &mut self.bytes[..]
243 }
244
245 #[inline]
247 pub fn push_ascii(&mut self, ascii: u8) {
248 assert!(ascii < 128);
249 self.bytes[self.pos] = ascii;
250 self.pos += 1;
251 }
252
253 #[inline]
255 pub fn push_str(&mut self, string: &str) {
256 let bytes = string.as_bytes();
257 self.bytes[self.pos..(self.pos + bytes.len())].copy_from_slice(bytes);
258 self.pos += bytes.len();
259 }
260
261 pub fn clear(&mut self) {
263 for b in &mut self.bytes[..self.pos] {
264 *b = 0;
265 }
266 self.pos = 0;
267 }
268
269 #[inline]
270 pub fn reborrow(&mut self) -> Builder<'_> {
271 Builder {
272 bytes: self.bytes,
273 pos: self.pos,
274 }
275 }
276
277 #[inline]
278 pub fn into_reader(self) -> Reader<'a> {
279 Reader(self.bytes)
280 }
281
282 #[inline]
283 pub fn reborrow_as_reader(&self) -> Reader<'_> {
284 Reader(self.bytes)
285 }
286}
287
288impl core::fmt::Debug for Builder<'_> {
289 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
290 match self.reborrow_as_reader().to_str() {
291 Ok(s) => write!(f, "{s:?}"),
292 Err(_) => write!(f, "<invalid utf-8>"),
293 }
294 }
295}
296
297impl<'a> crate::traits::FromPointerBuilder<'a> for Builder<'a> {
298 fn init_pointer(builder: crate::private::layout::PointerBuilder<'a>, size: u32) -> Builder<'a> {
299 builder.init_text(size)
300 }
301 fn get_from_pointer(
302 builder: crate::private::layout::PointerBuilder<'a>,
303 default: Option<&'a [crate::Word]>,
304 ) -> Result<Builder<'a>> {
305 builder.get_text(default)
306 }
307}
308
309impl<'a> crate::traits::SetterInput<Owned> for Reader<'a> {
310 #[inline]
311 fn set_pointer_builder<'b>(
312 mut pointer: crate::private::layout::PointerBuilder<'b>,
313 value: Reader<'a>,
314 _canonicalize: bool,
315 ) -> Result<()> {
316 pointer.set_text(value);
317 Ok(())
318 }
319}
320
321impl<T: AsRef<str>> crate::traits::SetterInput<Owned> for T {
324 #[inline]
325 fn set_pointer_builder(
326 mut pointer: crate::private::layout::PointerBuilder<'_>,
327 value: T,
328 _canonicalize: bool,
329 ) -> Result<()> {
330 pointer.set_text(value.as_ref().into());
331 Ok(())
332 }
333}
334
335impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
336 fn from(t: Reader<'a>) -> crate::dynamic_value::Reader<'a> {
337 crate::dynamic_value::Reader::Text(t)
338 }
339}
340
341impl<'a> From<&'a str> for crate::dynamic_value::Reader<'a> {
342 fn from(t: &'a str) -> crate::dynamic_value::Reader<'a> {
343 crate::dynamic_value::Reader::Text(t.into())
344 }
345}
346
347impl<'a> From<Builder<'a>> for crate::dynamic_value::Builder<'a> {
348 fn from(t: Builder<'a>) -> crate::dynamic_value::Builder<'a> {
349 crate::dynamic_value::Builder::Text(t)
350 }
351}