1use alloc::borrow::{Cow, ToOwned};
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, RawLimits, 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 {
51 fn info() -> &'static RawFormatInfo;
56}
57
58pub unsafe trait TextRawFormat: RawFormat {}
68
69pub struct RawFormatId {
78 name: &'static str,
79 is_text: bool,
80}
81
82impl RawFormatId {
83 pub const fn new(name: &'static str, is_text: bool) -> RawFormatId {
89 RawFormatId { name, is_text }
90 }
91
92 pub fn name(&self) -> &'static str {
94 self.name
95 }
96
97 pub fn is_text(&self) -> bool {
99 self.is_text
100 }
101}
102
103impl fmt::Debug for RawFormatId {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 f.debug_tuple("RawFormatId").field(&self.name).finish()
106 }
107}
108
109type CheckRawLimits = fn(&[u8], &mut RawLimits) -> Result<(), Error>;
110
111pub struct RawFormatInfo {
118 id: &'static RawFormatId,
119 replay: for<'de> fn(&'de [u8], &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>,
120 encode: fn(SerializeRef<'_>) -> Result<Vec<u8>, Error>,
121 fallback: for<'v> fn(&'v [u8]) -> Atom<'v>,
122 data: Option<&'static (dyn Any + Send + Sync)>,
123 check_limits: Option<CheckRawLimits>,
124}
125
126impl RawFormatInfo {
127 pub const fn new(
137 id: &'static RawFormatId,
138 replay: for<'de> fn(&'de [u8], &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>,
139 encode: fn(SerializeRef<'_>) -> Result<Vec<u8>, Error>,
140 fallback: for<'v> fn(&'v [u8]) -> Atom<'v>,
141 ) -> RawFormatInfo {
142 RawFormatInfo {
143 id,
144 replay,
145 encode,
146 fallback,
147 data: None,
148 check_limits: None,
149 }
150 }
151
152 pub const fn set_data(&mut self, data: &'static (dyn Any + Send + Sync)) {
160 self.data = Some(data);
161 }
162
163 #[doc(hidden)]
165 pub const fn set_check_limits(&mut self, check: CheckRawLimits) {
166 self.check_limits = Some(check);
167 }
168
169 pub fn data(&self) -> Option<&'static (dyn Any + Send + Sync)> {
171 self.data
172 }
173
174 pub fn id(&self) -> &'static RawFormatId {
176 self.id
177 }
178
179 pub fn name(&self) -> &'static str {
181 self.id.name
182 }
183
184 pub fn is_text(&self) -> bool {
186 self.id.is_text
187 }
188
189 fn record<'a>(&self, bytes: &'a [u8]) -> Result<RecordBuf<'a>, Error> {
191 let mut recording = RecordBuf::new();
192 {
193 let mut driver = DeserializeDriver::from_fn(|state| recording.recorder(state));
194 (self.replay)(bytes, &mut driver)?;
195 }
196 Ok(recording)
197 }
198}
199
200impl fmt::Debug for RawFormatInfo {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 f.debug_tuple("RawFormatInfo").field(&self.id.name).finish()
203 }
204}
205
206#[inline(always)]
208fn same_format(a: &'static RawFormatInfo, b: &'static RawFormatInfo) -> bool {
209 core::ptr::eq(a.id, b.id)
210}
211
212#[derive(Clone)]
227pub struct RawInput<'a> {
228 bytes: Cow<'a, [u8]>,
229 format: &'static RawFormatInfo,
230}
231
232impl<'a> RawInput<'a> {
233 pub unsafe fn new<B: Into<Cow<'a, [u8]>>>(
249 bytes: B,
250 format: &'static RawFormatInfo,
251 ) -> RawInput<'a> {
252 let bytes = bytes.into();
253 debug_assert!(!format.is_text() || core::str::from_utf8(&bytes).is_ok());
254 RawInput { bytes, format }
255 }
256
257 pub fn as_bytes(&self) -> &[u8] {
259 &self.bytes
260 }
261
262 pub fn as_str(&self) -> Option<&str> {
264 self.format
266 .is_text()
267 .then(|| unsafe { core::str::from_utf8_unchecked(&self.bytes) })
268 }
269
270 pub fn format(&self) -> &'static RawFormatInfo {
272 self.format
273 }
274
275 pub fn is<F: RawFormat>(&self) -> bool {
277 same_format(self.format, F::info())
278 }
279
280 pub fn is_format(&self, id: &'static RawFormatId) -> bool {
286 core::ptr::eq(self.format.id, id)
287 }
288
289 pub fn into_owned(self) -> RawInput<'static> {
291 RawInput {
292 bytes: Cow::Owned(self.bytes.into_owned()),
293 format: self.format,
294 }
295 }
296
297 pub fn record(&self) -> Result<RecordBuf<'_>, Error> {
299 self.format.record(&self.bytes)
300 }
301
302 pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
306 self.replay_raw(sink, None, state)
308 }
309
310 fn replay_raw<'x>(
312 &'x self,
313 sink: SinkHandle<'_, 'x>,
314 raw: Option<&'static RawFormatInfo>,
315 state: &mut State,
316 ) -> Result<(), Error> {
317 DeserializeDriver::nested(state, sink, false, |driver| {
318 driver.state_mut().raw_requested = raw;
320 (self.format.replay)(&self.bytes, driver)
321 })
322 }
323
324 pub(crate) fn check_limits(&self, limits: &mut RawLimits) -> Result<(), Error> {
326 let result = match self.format.check_limits {
327 Some(check) => check(&self.bytes, limits),
328 None => {
329 let mut state = State::new();
330 self.replay(
331 SinkHandle::arena(LimitSink { limits, end: None }, &mut state),
332 &mut state,
333 )
334 }
335 };
336 result.map_err(|err| Error::new(err.kind(), err.message().to_owned()))
339 }
340
341 pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
345 crate::de::deserialize_value(|driver| (self.format.replay)(&self.bytes, driver))
347 }
348}
349
350pub(crate) fn parse_into<'de>(
354 input: &RawInput<'_>,
355 sink: &mut (dyn Sink<'de> + '_),
356 state: &mut State,
357) -> Result<(), Error> {
358 let mut sink = NoFinish(sink);
359 DeserializeDriver::nested(state, SinkHandle::to(&mut sink), false, |driver| {
360 driver.state_mut().raw_requested = None;
361 driver.transient(|driver| (input.format.replay)(&input.bytes, driver))
363 })
364}
365
366struct LimitSink<'a> {
368 limits: &'a mut RawLimits,
369 end: Option<crate::Event<'static>>,
370}
371
372impl<'de> Sink<'de> for LimitSink<'_> {
373 fn atom(&mut self, atom: Atom, _state: &mut State) -> Result<(), Error> {
374 self.limits.event(atom.into())
375 }
376
377 fn map(&mut self, _state: &mut State) -> Result<(), Error> {
378 self.end = Some(crate::Event::MapEnd);
379 self.limits.event(crate::Event::map_start())
380 }
381
382 fn seq(&mut self, _state: &mut State) -> Result<(), Error> {
383 self.end = Some(crate::Event::SeqEnd);
384 self.limits.event(crate::Event::seq_start())
385 }
386
387 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
388 self.next_value(state)
389 }
390
391 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
392 Ok(SinkHandle::arena(
393 LimitSink {
394 limits: self.limits,
395 end: None,
396 },
397 state,
398 ))
399 }
400
401 fn finish(&mut self, _state: &mut State) -> Result<(), Error> {
402 match self.end.take() {
403 Some(event) => self.limits.event(event),
404 None => Ok(()),
405 }
406 }
407}
408
409struct NoFinish<'a, 'b, 'de>(&'a mut (dyn Sink<'de> + 'b));
415
416impl<'de> Sink<'de> for NoFinish<'_, '_, 'de> {
417 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
418 self.0.atom(atom, state)
419 }
420
421 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
422 self.0.borrowed_atom(atom, state)
423 }
424
425 fn map(&mut self, state: &mut State) -> Result<(), Error> {
426 self.0.map(state)
427 }
428
429 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
430 self.0.seq(state)
431 }
432
433 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
434 self.0.next_key(state)
435 }
436
437 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
438 self.0.next_value(state)
439 }
440
441 fn value_for_key(
442 &mut self,
443 key: &str,
444 state: &mut State,
445 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
446 self.0.value_for_key(key, state)
447 }
448
449 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
450 self.0.recover(err, state)
451 }
452
453 fn expecting(&self) -> Cow<'_, str> {
454 self.0.expecting()
455 }
456
457 fn finish(&mut self, _state: &mut State) -> Result<(), Error> {
458 Ok(())
459 }
460}
461
462impl fmt::Debug for RawInput<'_> {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 let mut debug = f.debug_struct("RawInput");
465 debug.field("format", &self.format.id.name);
466 match self.as_str() {
467 Some(text) => debug.field("text", &text),
468 None => debug.field("bytes", &self.bytes),
469 };
470 debug.finish()
471 }
472}
473
474impl PartialEq for RawInput<'_> {
475 fn eq(&self, other: &Self) -> bool {
476 same_format(self.format, other.format) && self.bytes == other.bytes
477 }
478}
479
480impl BorrowedExtension for RawInput<'static> {
481 type Value<'a> = RawInput<'a>;
482
483 fn name<'v>(_value: &'v RawInput<'_>) -> &'v str {
484 "raw value"
485 }
486
487 fn fallback<'v>(value: &'v RawInput<'_>) -> Atom<'v> {
488 (value.format.fallback)(&value.bytes)
489 }
490
491 fn to_static(value: &RawInput<'_>) -> RawInput<'static> {
492 value.clone().into_owned()
493 }
494
495 fn shorten<'s, 'l: 's>(value: &'s RawInput<'l>) -> &'s RawInput<'s> {
496 value
497 }
498}
499
500fn serialize_input<'a>(input: &'a RawInput<'_>, state: &mut State) -> Result<Emit<'a>, Error> {
505 if state.accepts_raw(input.format) {
506 return Ok(Emit::Atom(Atom::Ext(ExtValue::borrowed_value::<RawInput>(
507 input,
508 ))));
509 }
510 Ok(Emit::Forward(SerializeHandle::arena(
511 input.record()?,
512 state,
513 )))
514}
515
516pub(crate) fn serialize_recorded_atom<'a>(
521 atom: &'a Atom<'_>,
522 state: &mut State,
523) -> Result<Emit<'a>, Error> {
524 if let Atom::Ext(ext) = atom
525 && let Some(input) = ext.downcast_value_ref::<RawInput>()
526 {
527 return serialize_input(input, state);
528 }
529 Ok(Emit::Atom(atom.as_borrowed()))
530}
531
532pub struct Raw<'a, F: RawFormat> {
563 input: RawInput<'a>,
564 _format: PhantomData<fn() -> F>,
565}
566
567impl<'a, F: RawFormat> Raw<'a, F> {
568 pub fn new<B: Into<Cow<'a, [u8]>>>(bytes: B) -> Result<Raw<'a, F>, Error> {
572 let bytes = bytes.into();
573 let info = F::info();
574 if info.is_text() && core::str::from_utf8(&bytes).is_err() {
575 return Err(Error::new(ErrorKind::Syntax, "invalid utf-8"));
576 }
577 {
578 let mut driver = DeserializeDriver::from_fn(|_| SinkHandle::null());
579 (info.replay)(&bytes, &mut driver)?;
580 }
581 Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
583 }
584
585 pub fn encode<T: Serialize + ?Sized>(value: &T) -> Result<Raw<'static, F>, Error> {
587 let info = F::info();
588 let bytes = (info.encode)(SerializeRef::new(&value))?;
589 if info.is_text() && core::str::from_utf8(&bytes).is_err() {
590 return Err(Error::new(
591 ErrorKind::InvalidState,
592 "the encoding of a text format is not utf-8",
593 ));
594 }
595 Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
597 }
598
599 fn from_input(input: RawInput<'a>) -> Raw<'a, F> {
600 debug_assert!(input.is::<F>());
601 Raw {
602 input,
603 _format: PhantomData,
604 }
605 }
606
607 pub fn as_bytes(&self) -> &[u8] {
609 &self.input.bytes
610 }
611
612 pub fn is_borrowed(&self) -> bool {
615 matches!(self.input.bytes, Cow::Borrowed(_))
616 }
617
618 pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
622 self.input.replay(sink, state)
623 }
624
625 pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
629 self.input.deserialize()
630 }
631
632 pub fn into_owned(self) -> Raw<'static, F> {
634 Raw::from_input(self.input.into_owned())
635 }
636
637 #[inline(never)]
639 fn from_atom(atom: Atom<'_>, state: &State) -> Result<Raw<'static, F>, Error> {
640 if let Atom::Ext(ref ext) = atom
641 && let Some(input) = ext.downcast_value_ref::<RawInput>()
642 {
643 if input.is::<F>() {
644 return Ok(Raw::from_input(input.clone().into_owned()));
645 }
646 return Raw::encode(&input.record()?);
647 }
648 let mut recording = RecordBuf::new();
649 recording.set_atom(&atom, state);
650 Raw::encode(&recording)
651 }
652}
653
654impl<'de, F: RawFormat> Raw<'de, F> {
655 #[inline(never)]
657 fn from_borrowed_atom(atom: Atom<'de>, state: &State) -> Result<Raw<'de, F>, Error> {
658 if let Atom::Ext(ref ext) = atom {
659 if let Some(input) = unsafe { ext.downcast_value_ref_covariant::<RawInput>() }
661 && input.is::<F>()
662 {
663 return Ok(Raw::from_input(input.clone()));
664 }
665 }
666 Raw::from_atom(atom, state)
667 }
668}
669
670impl<F: TextRawFormat> Raw<'_, F> {
671 pub fn get(&self) -> &str {
673 unsafe { core::str::from_utf8_unchecked(&self.input.bytes) }
675 }
676}
677
678impl<F: RawFormat> Clone for Raw<'_, F> {
679 fn clone(&self) -> Self {
680 Raw::from_input(self.input.clone())
681 }
682}
683
684impl<F: RawFormat> fmt::Debug for Raw<'_, F> {
685 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
686 let mut debug = f.debug_tuple("Raw");
687 debug.field(&self.input.format.id.name);
688 match self.input.as_str() {
689 Some(text) => debug.field(&text),
690 None => debug.field(&self.input.bytes),
691 };
692 debug.finish()
693 }
694}
695
696impl<F: RawFormat> PartialEq for Raw<'_, F> {
698 fn eq(&self, other: &Self) -> bool {
699 self.input.bytes == other.input.bytes
700 }
701}
702
703impl<F: RawFormat> Eq for Raw<'_, F> {}
704
705impl<F: RawFormat> core::hash::Hash for Raw<'_, F> {
706 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
707 self.input.bytes.hash(state)
708 }
709}
710
711impl<F: RawFormat> Serialize for Raw<'_, F> {
714 fn serialize<'a>(value: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
715 serialize_input(&value.input, state)
716 }
717}
718
719impl<'de, 'a, F: RawFormat> Deserialize<'de> for Raw<'a, F> {
723 fn deserialize_into<'out>(
724 out: &'out mut Option<Self>,
725 state: &mut State,
726 ) -> SinkHandle<'out, 'de> {
727 RecordBuf::capture_with(RawCapture(out), state)
728 }
729
730 fn expecting() -> Cow<'static, str> {
731 Cow::Borrowed("any value")
732 }
733
734 #[inline]
735 fn __private_atom_into(
736 out: &mut Option<Self>,
737 atom: Atom,
738 state: &mut State,
739 ) -> Result<(), Error> {
740 *out = Some(Raw::from_atom(atom, state)?);
741 Ok(())
742 }
743
744 #[inline]
745 fn __private_borrowed_atom_into(
746 out: &mut Option<Self>,
747 atom: Atom<'de>,
748 state: &mut State,
749 ) -> Result<(), Error> {
750 *out = Some(Raw::from_atom(atom, state)?);
751 Ok(())
752 }
753
754 #[inline(always)]
755 fn __private_raw() -> Option<&'static RawFormatInfo> {
756 Some(F::info())
757 }
758}
759
760impl<'de: 'a, 'a, F: RawFormat> Deserialize<'de, Raw<'a, F>> for Borrowed {
762 fn deserialize_into<'out>(
763 out: &'out mut Option<Raw<'a, F>>,
764 state: &mut State,
765 ) -> SinkHandle<'out, 'de> {
766 RecordBuf::capture_with(BorrowedRawCapture(out), state)
767 }
768
769 fn expecting() -> Cow<'static, str> {
770 Cow::Borrowed("any value")
771 }
772
773 #[inline]
774 fn __private_atom_into(
775 out: &mut Option<Raw<'a, F>>,
776 atom: Atom,
777 state: &mut State,
778 ) -> Result<(), Error> {
779 *out = Some(Raw::from_atom(atom, state)?);
780 Ok(())
781 }
782
783 #[inline]
784 fn __private_borrowed_atom_into(
785 out: &mut Option<Raw<'a, F>>,
786 atom: Atom<'de>,
787 state: &mut State,
788 ) -> Result<(), Error> {
789 *out = Some(Raw::from_borrowed_atom(atom, state)?);
790 Ok(())
791 }
792
793 #[inline(always)]
794 fn __private_raw() -> Option<&'static RawFormatInfo> {
795 Some(F::info())
796 }
797}
798
799impl<'a, F: RawFormat> Serialize<Raw<'a, F>> for Borrowed {
800 fn serialize<'x>(value: &'x Raw<'a, F>, state: &mut State) -> Result<Emit<'x>, Error> {
801 <Raw<'a, F>>::serialize(value, state)
802 }
803}
804
805struct RawCapture<'o, 'a, F: RawFormat>(&'o mut Option<Raw<'a, F>>);
807
808impl<'o, 'a, 'de, F: RawFormat> Capture<'de, RecordBuf<'de>> for RawCapture<'o, 'a, F> {
809 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
810 *self.0 = Some(Raw::from_atom(atom, state)?);
811 Ok(())
812 }
813
814 fn recorded(&mut self, recording: RecordBuf<'de>, _state: &mut State) -> Result<(), Error> {
815 *self.0 = Some(Raw::encode(&recording)?);
816 Ok(())
817 }
818}
819
820struct BorrowedRawCapture<'o, 'a, F: RawFormat>(&'o mut Option<Raw<'a, F>>);
822
823impl<'o, 'a, 'de: 'a, F: RawFormat> Capture<'de, RecordBuf<'de>> for BorrowedRawCapture<'o, 'a, F> {
824 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
825 *self.0 = Some(Raw::from_atom(atom, state)?);
826 Ok(())
827 }
828
829 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
830 *self.0 = Some(Raw::from_borrowed_atom(atom, state)?);
831 Ok(())
832 }
833
834 fn recorded(&mut self, recording: RecordBuf<'de>, _state: &mut State) -> Result<(), Error> {
835 *self.0 = Some(Raw::encode(&recording)?);
836 Ok(())
837 }
838}