1use alloc::borrow::Cow;
2use alloc::vec::Vec;
3use core::any::Any;
4use core::fmt;
5use core::marker::PhantomData;
6
7use crate::State;
8use crate::adapters::Borrowed;
9use crate::de::recording::Capture;
10use crate::de::{Deserialize, DeserializeDriver, RecordBuf, Sink, SinkHandle};
11use crate::error::{Error, ErrorKind};
12use crate::event::Atom;
13use crate::ext::{BorrowedExtension, ExtValue};
14use crate::ser::{Emit, Serialize, SerializeHandle, SerializeRef};
15
16pub trait RawFormat: 'static {
49 fn info() -> &'static RawFormatInfo;
54}
55
56pub unsafe trait TextRawFormat: RawFormat {}
66
67pub struct RawFormatId {
76 name: &'static str,
77 is_text: bool,
78}
79
80impl RawFormatId {
81 pub const fn new(name: &'static str, is_text: bool) -> RawFormatId {
87 RawFormatId { name, is_text }
88 }
89
90 pub fn name(&self) -> &'static str {
92 self.name
93 }
94
95 pub fn is_text(&self) -> bool {
97 self.is_text
98 }
99}
100
101impl fmt::Debug for RawFormatId {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 f.debug_tuple("RawFormatId").field(&self.name).finish()
104 }
105}
106
107pub struct RawFormatInfo {
114 id: &'static RawFormatId,
115 replay: for<'de> fn(&'de [u8], &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>,
116 encode: fn(SerializeRef<'_>) -> Result<Vec<u8>, Error>,
117 fallback: for<'v> fn(&'v [u8]) -> Atom<'v>,
118 data: Option<&'static (dyn Any + Send + Sync)>,
119}
120
121impl RawFormatInfo {
122 pub const fn new(
132 id: &'static RawFormatId,
133 replay: for<'de> fn(&'de [u8], &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>,
134 encode: fn(SerializeRef<'_>) -> Result<Vec<u8>, Error>,
135 fallback: for<'v> fn(&'v [u8]) -> Atom<'v>,
136 ) -> RawFormatInfo {
137 RawFormatInfo {
138 id,
139 replay,
140 encode,
141 fallback,
142 data: None,
143 }
144 }
145
146 pub const fn set_data(&mut self, data: &'static (dyn Any + Send + Sync)) {
154 self.data = Some(data);
155 }
156
157 pub fn data(&self) -> Option<&'static (dyn Any + Send + Sync)> {
159 self.data
160 }
161
162 pub fn id(&self) -> &'static RawFormatId {
164 self.id
165 }
166
167 pub fn name(&self) -> &'static str {
169 self.id.name
170 }
171
172 pub fn is_text(&self) -> bool {
174 self.id.is_text
175 }
176
177 fn record<'a>(&self, bytes: &'a [u8]) -> Result<RecordBuf<'a>, Error> {
179 let mut recording = RecordBuf::new();
180 {
181 let mut driver = DeserializeDriver::from_fn(|state| recording.recorder(state));
182 (self.replay)(bytes, &mut driver)?;
183 }
184 Ok(recording)
185 }
186}
187
188impl fmt::Debug for RawFormatInfo {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 f.debug_tuple("RawFormatInfo").field(&self.id.name).finish()
191 }
192}
193
194#[inline(always)]
196fn same_format(a: &'static RawFormatInfo, b: &'static RawFormatInfo) -> bool {
197 core::ptr::eq(a.id, b.id)
198}
199
200#[derive(Clone)]
215pub struct RawInput<'a> {
216 bytes: Cow<'a, [u8]>,
217 format: &'static RawFormatInfo,
218}
219
220impl<'a> RawInput<'a> {
221 pub unsafe fn new<B: Into<Cow<'a, [u8]>>>(
229 bytes: B,
230 format: &'static RawFormatInfo,
231 ) -> RawInput<'a> {
232 RawInput {
233 bytes: bytes.into(),
234 format,
235 }
236 }
237
238 pub fn as_bytes(&self) -> &[u8] {
240 &self.bytes
241 }
242
243 pub fn as_str(&self) -> Option<&str> {
245 self.format
247 .is_text()
248 .then(|| unsafe { core::str::from_utf8_unchecked(&self.bytes) })
249 }
250
251 pub fn format(&self) -> &'static RawFormatInfo {
253 self.format
254 }
255
256 pub fn is<F: RawFormat>(&self) -> bool {
258 same_format(self.format, F::info())
259 }
260
261 pub fn is_format(&self, id: &'static RawFormatId) -> bool {
267 core::ptr::eq(self.format.id, id)
268 }
269
270 pub fn into_owned(self) -> RawInput<'static> {
272 RawInput {
273 bytes: Cow::Owned(self.bytes.into_owned()),
274 format: self.format,
275 }
276 }
277
278 pub fn record(&self) -> Result<RecordBuf<'_>, Error> {
280 self.format.record(&self.bytes)
281 }
282
283 pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
287 self.replay_raw(sink, None, state)
289 }
290
291 fn replay_raw<'x>(
293 &'x self,
294 sink: SinkHandle<'_, 'x>,
295 raw: Option<&'static RawFormatInfo>,
296 state: &mut State,
297 ) -> Result<(), Error> {
298 DeserializeDriver::nested(state, sink, false, |driver| {
299 driver.state_mut().raw_requested = raw;
301 (self.format.replay)(&self.bytes, driver)
302 })
303 }
304
305 pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
309 crate::de::deserialize_value(|driver| (self.format.replay)(&self.bytes, driver))
311 }
312}
313
314pub(crate) fn parse_into<'de>(
318 input: &RawInput<'_>,
319 sink: &mut (dyn Sink<'de> + '_),
320 state: &mut State,
321) -> Result<(), Error> {
322 let mut sink = NoFinish(sink);
323 DeserializeDriver::nested(state, SinkHandle::to(&mut sink), false, |driver| {
324 driver.state_mut().raw_requested = None;
325 driver.transient(|driver| (input.format.replay)(&input.bytes, driver))
327 })
328}
329
330struct NoFinish<'a, 'b, 'de>(&'a mut (dyn Sink<'de> + 'b));
336
337impl<'de> Sink<'de> for NoFinish<'_, '_, 'de> {
338 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
339 self.0.atom(atom, state)
340 }
341
342 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
343 self.0.borrowed_atom(atom, state)
344 }
345
346 fn map(&mut self, state: &mut State) -> Result<(), Error> {
347 self.0.map(state)
348 }
349
350 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
351 self.0.seq(state)
352 }
353
354 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
355 self.0.next_key(state)
356 }
357
358 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
359 self.0.next_value(state)
360 }
361
362 fn value_for_key(
363 &mut self,
364 key: &str,
365 state: &mut State,
366 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
367 self.0.value_for_key(key, state)
368 }
369
370 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
371 self.0.recover(err, state)
372 }
373
374 fn expecting(&self) -> Cow<'_, str> {
375 self.0.expecting()
376 }
377
378 fn finish(&mut self, _state: &mut State) -> Result<(), Error> {
379 Ok(())
380 }
381}
382
383impl fmt::Debug for RawInput<'_> {
384 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
385 let mut debug = f.debug_struct("RawInput");
386 debug.field("format", &self.format.id.name);
387 match self.as_str() {
388 Some(text) => debug.field("text", &text),
389 None => debug.field("bytes", &self.bytes),
390 };
391 debug.finish()
392 }
393}
394
395impl PartialEq for RawInput<'_> {
396 fn eq(&self, other: &Self) -> bool {
397 same_format(self.format, other.format) && self.bytes == other.bytes
398 }
399}
400
401impl BorrowedExtension for RawInput<'static> {
402 type Value<'a> = RawInput<'a>;
403
404 fn name<'v>(_value: &'v RawInput<'_>) -> &'v str {
405 "raw value"
406 }
407
408 fn fallback<'v>(value: &'v RawInput<'_>) -> Atom<'v> {
409 (value.format.fallback)(&value.bytes)
410 }
411
412 fn to_static(value: &RawInput<'_>) -> RawInput<'static> {
413 value.clone().into_owned()
414 }
415
416 fn shorten<'s, 'l: 's>(value: &'s RawInput<'l>) -> &'s RawInput<'s> {
417 value
418 }
419}
420
421fn serialize_input<'a>(input: &'a RawInput<'_>, state: &mut State) -> Result<Emit<'a>, Error> {
426 if state.accepts_raw(input.format) {
427 return Ok(Emit::Atom(Atom::Ext(ExtValue::borrowed_value::<RawInput>(
428 input,
429 ))));
430 }
431 Ok(Emit::Forward(SerializeHandle::arena(
432 input.record()?,
433 state,
434 )))
435}
436
437pub(crate) fn serialize_recorded_atom<'a>(
442 atom: &'a Atom<'_>,
443 state: &mut State,
444) -> Result<Emit<'a>, Error> {
445 if let Atom::Ext(ext) = atom
446 && let Some(input) = ext.downcast_value_ref::<RawInput>()
447 {
448 return serialize_input(input, state);
449 }
450 Ok(Emit::Atom(atom.as_borrowed()))
451}
452
453pub struct Raw<'a, F: RawFormat> {
484 input: RawInput<'a>,
485 _format: PhantomData<fn() -> F>,
486}
487
488impl<'a, F: RawFormat> Raw<'a, F> {
489 pub fn new<B: Into<Cow<'a, [u8]>>>(bytes: B) -> Result<Raw<'a, F>, Error> {
493 let bytes = bytes.into();
494 let info = F::info();
495 if info.is_text() && core::str::from_utf8(&bytes).is_err() {
496 return Err(Error::new(ErrorKind::Syntax, "invalid utf-8"));
497 }
498 {
499 let mut driver = DeserializeDriver::from_fn(|_| SinkHandle::null());
500 (info.replay)(&bytes, &mut driver)?;
501 }
502 Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
504 }
505
506 pub fn encode<T: Serialize + ?Sized>(value: &T) -> Result<Raw<'static, F>, Error> {
508 let info = F::info();
509 let bytes = (info.encode)(SerializeRef::new(&value))?;
510 if info.is_text() && core::str::from_utf8(&bytes).is_err() {
511 return Err(Error::new(
512 ErrorKind::InvalidState,
513 "the encoding of a text format is not utf-8",
514 ));
515 }
516 Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
518 }
519
520 fn from_input(input: RawInput<'a>) -> Raw<'a, F> {
521 debug_assert!(input.is::<F>());
522 Raw {
523 input,
524 _format: PhantomData,
525 }
526 }
527
528 pub fn as_bytes(&self) -> &[u8] {
530 &self.input.bytes
531 }
532
533 pub fn is_borrowed(&self) -> bool {
536 matches!(self.input.bytes, Cow::Borrowed(_))
537 }
538
539 pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
543 self.input.replay(sink, state)
544 }
545
546 pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
550 self.input.deserialize()
551 }
552
553 pub fn into_owned(self) -> Raw<'static, F> {
555 Raw::from_input(self.input.into_owned())
556 }
557
558 #[inline(never)]
560 fn from_atom(atom: Atom<'_>, state: &State) -> Result<Raw<'static, F>, Error> {
561 if let Atom::Ext(ref ext) = atom
562 && let Some(input) = ext.downcast_value_ref::<RawInput>()
563 {
564 if input.is::<F>() {
565 return Ok(Raw::from_input(input.clone().into_owned()));
566 }
567 return Raw::encode(&input.record()?);
568 }
569 let mut recording = RecordBuf::new();
570 recording.set_atom(&atom, state);
571 Raw::encode(&recording)
572 }
573}
574
575impl<'de, F: RawFormat> Raw<'de, F> {
576 #[inline(never)]
578 fn from_borrowed_atom(atom: Atom<'de>, state: &State) -> Result<Raw<'de, F>, Error> {
579 if let Atom::Ext(ref ext) = atom {
580 if let Some(input) = unsafe { ext.downcast_value_ref_covariant::<RawInput>() }
582 && input.is::<F>()
583 {
584 return Ok(Raw::from_input(input.clone()));
585 }
586 }
587 Raw::from_atom(atom, state)
588 }
589}
590
591impl<F: TextRawFormat> Raw<'_, F> {
592 pub fn get(&self) -> &str {
594 unsafe { core::str::from_utf8_unchecked(&self.input.bytes) }
596 }
597}
598
599impl<F: RawFormat> Clone for Raw<'_, F> {
600 fn clone(&self) -> Self {
601 Raw::from_input(self.input.clone())
602 }
603}
604
605impl<F: RawFormat> fmt::Debug for Raw<'_, F> {
606 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
607 let mut debug = f.debug_tuple("Raw");
608 debug.field(&self.input.format.id.name);
609 match self.input.as_str() {
610 Some(text) => debug.field(&text),
611 None => debug.field(&self.input.bytes),
612 };
613 debug.finish()
614 }
615}
616
617impl<F: RawFormat> PartialEq for Raw<'_, F> {
619 fn eq(&self, other: &Self) -> bool {
620 self.input.bytes == other.input.bytes
621 }
622}
623
624impl<F: RawFormat> Eq for Raw<'_, F> {}
625
626impl<F: RawFormat> core::hash::Hash for Raw<'_, F> {
627 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
628 self.input.bytes.hash(state)
629 }
630}
631
632impl<F: RawFormat> Serialize for Raw<'_, F> {
635 fn serialize<'a>(value: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
636 serialize_input(&value.input, state)
637 }
638}
639
640impl<'de, 'a, F: RawFormat> Deserialize<'de> for Raw<'a, F> {
644 fn deserialize_into<'out>(
645 out: &'out mut Option<Self>,
646 state: &mut State,
647 ) -> SinkHandle<'out, 'de> {
648 RecordBuf::capture_with(RawCapture(out), state)
649 }
650
651 fn expecting() -> Cow<'static, str> {
652 Cow::Borrowed("any value")
653 }
654
655 #[inline]
656 fn __private_atom_into(
657 out: &mut Option<Self>,
658 atom: Atom,
659 state: &mut State,
660 ) -> Result<(), Error> {
661 *out = Some(Raw::from_atom(atom, state)?);
662 Ok(())
663 }
664
665 #[inline]
666 fn __private_borrowed_atom_into(
667 out: &mut Option<Self>,
668 atom: Atom<'de>,
669 state: &mut State,
670 ) -> Result<(), Error> {
671 *out = Some(Raw::from_atom(atom, state)?);
672 Ok(())
673 }
674
675 #[inline(always)]
676 fn __private_raw() -> Option<&'static RawFormatInfo> {
677 Some(F::info())
678 }
679}
680
681impl<'de: 'a, 'a, F: RawFormat> Deserialize<'de, Raw<'a, F>> for Borrowed {
683 fn deserialize_into<'out>(
684 out: &'out mut Option<Raw<'a, F>>,
685 state: &mut State,
686 ) -> SinkHandle<'out, 'de> {
687 RecordBuf::capture_with(BorrowedRawCapture(out), state)
688 }
689
690 fn expecting() -> Cow<'static, str> {
691 Cow::Borrowed("any value")
692 }
693
694 #[inline]
695 fn __private_atom_into(
696 out: &mut Option<Raw<'a, F>>,
697 atom: Atom,
698 state: &mut State,
699 ) -> Result<(), Error> {
700 *out = Some(Raw::from_atom(atom, state)?);
701 Ok(())
702 }
703
704 #[inline]
705 fn __private_borrowed_atom_into(
706 out: &mut Option<Raw<'a, F>>,
707 atom: Atom<'de>,
708 state: &mut State,
709 ) -> Result<(), Error> {
710 *out = Some(Raw::from_borrowed_atom(atom, state)?);
711 Ok(())
712 }
713
714 #[inline(always)]
715 fn __private_raw() -> Option<&'static RawFormatInfo> {
716 Some(F::info())
717 }
718}
719
720impl<'a, F: RawFormat> Serialize<Raw<'a, F>> for Borrowed {
721 fn serialize<'x>(value: &'x Raw<'a, F>, state: &mut State) -> Result<Emit<'x>, Error> {
722 <Raw<'a, F>>::serialize(value, state)
723 }
724}
725
726struct RawCapture<'o, 'a, F: RawFormat>(&'o mut Option<Raw<'a, F>>);
728
729impl<'o, 'a, 'de, F: RawFormat> Capture<'de, RecordBuf<'de>> for RawCapture<'o, 'a, F> {
730 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
731 *self.0 = Some(Raw::from_atom(atom, state)?);
732 Ok(())
733 }
734
735 fn recorded(&mut self, recording: RecordBuf<'de>, _state: &mut State) -> Result<(), Error> {
736 *self.0 = Some(Raw::encode(&recording)?);
737 Ok(())
738 }
739}
740
741struct BorrowedRawCapture<'o, 'a, F: RawFormat>(&'o mut Option<Raw<'a, F>>);
743
744impl<'o, 'a, 'de: 'a, F: RawFormat> Capture<'de, RecordBuf<'de>> for BorrowedRawCapture<'o, 'a, F> {
745 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
746 *self.0 = Some(Raw::from_atom(atom, state)?);
747 Ok(())
748 }
749
750 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
751 *self.0 = Some(Raw::from_borrowed_atom(atom, state)?);
752 Ok(())
753 }
754
755 fn recorded(&mut self, recording: RecordBuf<'de>, _state: &mut State) -> Result<(), Error> {
756 *self.0 = Some(Raw::encode(&recording)?);
757 Ok(())
758 }
759}