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 {
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
109pub struct RawFormatInfo {
116 id: &'static RawFormatId,
117 replay: for<'de> fn(&'de [u8], &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>,
118 encode: fn(SerializeRef<'_>) -> Result<Vec<u8>, Error>,
119 fallback: for<'v> fn(&'v [u8]) -> Atom<'v>,
120 data: Option<&'static (dyn Any + Send + Sync)>,
121}
122
123impl RawFormatInfo {
124 pub const fn new(
134 id: &'static RawFormatId,
135 replay: for<'de> fn(&'de [u8], &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>,
136 encode: fn(SerializeRef<'_>) -> Result<Vec<u8>, Error>,
137 fallback: for<'v> fn(&'v [u8]) -> Atom<'v>,
138 ) -> RawFormatInfo {
139 RawFormatInfo {
140 id,
141 replay,
142 encode,
143 fallback,
144 data: None,
145 }
146 }
147
148 pub const fn set_data(&mut self, data: &'static (dyn Any + Send + Sync)) {
156 self.data = Some(data);
157 }
158
159 pub fn data(&self) -> Option<&'static (dyn Any + Send + Sync)> {
161 self.data
162 }
163
164 pub fn id(&self) -> &'static RawFormatId {
166 self.id
167 }
168
169 pub fn name(&self) -> &'static str {
171 self.id.name
172 }
173
174 pub fn is_text(&self) -> bool {
176 self.id.is_text
177 }
178
179 fn record<'a>(&self, bytes: &'a [u8]) -> Result<RecordBuf<'a>, Error> {
181 let mut recording = RecordBuf::new();
182 {
183 let mut driver = DeserializeDriver::from_fn(|state| recording.recorder(state));
184 (self.replay)(bytes, &mut driver)?;
185 }
186 Ok(recording)
187 }
188}
189
190impl fmt::Debug for RawFormatInfo {
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 f.debug_tuple("RawFormatInfo").field(&self.id.name).finish()
193 }
194}
195
196#[inline(always)]
198fn same_format(a: &'static RawFormatInfo, b: &'static RawFormatInfo) -> bool {
199 core::ptr::eq(a.id, b.id)
200}
201
202#[derive(Clone)]
217pub struct RawInput<'a> {
218 bytes: Cow<'a, [u8]>,
219 format: &'static RawFormatInfo,
220}
221
222impl<'a> RawInput<'a> {
223 pub unsafe fn new<B: Into<Cow<'a, [u8]>>>(
239 bytes: B,
240 format: &'static RawFormatInfo,
241 ) -> RawInput<'a> {
242 let bytes = bytes.into();
243 debug_assert!(!format.is_text() || core::str::from_utf8(&bytes).is_ok());
244 RawInput { bytes, format }
245 }
246
247 pub fn as_bytes(&self) -> &[u8] {
249 &self.bytes
250 }
251
252 pub fn as_str(&self) -> Option<&str> {
254 self.format
256 .is_text()
257 .then(|| unsafe { core::str::from_utf8_unchecked(&self.bytes) })
258 }
259
260 pub fn format(&self) -> &'static RawFormatInfo {
262 self.format
263 }
264
265 pub fn is<F: RawFormat>(&self) -> bool {
267 same_format(self.format, F::info())
268 }
269
270 pub fn is_format(&self, id: &'static RawFormatId) -> bool {
276 core::ptr::eq(self.format.id, id)
277 }
278
279 pub fn into_owned(self) -> RawInput<'static> {
281 RawInput {
282 bytes: Cow::Owned(self.bytes.into_owned()),
283 format: self.format,
284 }
285 }
286
287 pub fn record(&self) -> Result<RecordBuf<'_>, Error> {
289 self.format.record(&self.bytes)
290 }
291
292 pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
296 self.replay_raw(sink, None, state)
298 }
299
300 fn replay_raw<'x>(
302 &'x self,
303 sink: SinkHandle<'_, 'x>,
304 raw: Option<&'static RawFormatInfo>,
305 state: &mut State,
306 ) -> Result<(), Error> {
307 DeserializeDriver::nested(state, sink, false, |driver| {
308 driver.state_mut().raw_requested = raw;
310 (self.format.replay)(&self.bytes, driver)
311 })
312 }
313
314 pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
318 crate::de::deserialize_value(|driver| (self.format.replay)(&self.bytes, driver))
320 }
321}
322
323pub(crate) fn parse_into<'de>(
327 input: &RawInput<'_>,
328 sink: &mut (dyn Sink<'de> + '_),
329 state: &mut State,
330) -> Result<(), Error> {
331 let mut sink = NoFinish(sink);
332 DeserializeDriver::nested(state, SinkHandle::to(&mut sink), false, |driver| {
333 driver.state_mut().raw_requested = None;
334 driver.transient(|driver| (input.format.replay)(&input.bytes, driver))
336 })
337}
338
339struct NoFinish<'a, 'b, 'de>(&'a mut (dyn Sink<'de> + 'b));
345
346impl<'de> Sink<'de> for NoFinish<'_, '_, 'de> {
347 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
348 self.0.atom(atom, state)
349 }
350
351 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
352 self.0.borrowed_atom(atom, state)
353 }
354
355 fn map(&mut self, state: &mut State) -> Result<(), Error> {
356 self.0.map(state)
357 }
358
359 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
360 self.0.seq(state)
361 }
362
363 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
364 self.0.next_key(state)
365 }
366
367 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
368 self.0.next_value(state)
369 }
370
371 fn value_for_key(
372 &mut self,
373 key: &str,
374 state: &mut State,
375 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
376 self.0.value_for_key(key, state)
377 }
378
379 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
380 self.0.recover(err, state)
381 }
382
383 fn expecting(&self) -> Cow<'_, str> {
384 self.0.expecting()
385 }
386
387 fn finish(&mut self, _state: &mut State) -> Result<(), Error> {
388 Ok(())
389 }
390}
391
392impl fmt::Debug for RawInput<'_> {
393 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
394 let mut debug = f.debug_struct("RawInput");
395 debug.field("format", &self.format.id.name);
396 match self.as_str() {
397 Some(text) => debug.field("text", &text),
398 None => debug.field("bytes", &self.bytes),
399 };
400 debug.finish()
401 }
402}
403
404impl PartialEq for RawInput<'_> {
405 fn eq(&self, other: &Self) -> bool {
406 same_format(self.format, other.format) && self.bytes == other.bytes
407 }
408}
409
410impl BorrowedExtension for RawInput<'static> {
411 type Value<'a> = RawInput<'a>;
412
413 fn name<'v>(_value: &'v RawInput<'_>) -> &'v str {
414 "raw value"
415 }
416
417 fn fallback<'v>(value: &'v RawInput<'_>) -> Atom<'v> {
418 (value.format.fallback)(&value.bytes)
419 }
420
421 fn to_static(value: &RawInput<'_>) -> RawInput<'static> {
422 value.clone().into_owned()
423 }
424
425 fn shorten<'s, 'l: 's>(value: &'s RawInput<'l>) -> &'s RawInput<'s> {
426 value
427 }
428}
429
430fn serialize_input<'a>(input: &'a RawInput<'_>, state: &mut State) -> Result<Emit<'a>, Error> {
435 if state.accepts_raw(input.format) {
436 return Ok(Emit::Atom(Atom::Ext(ExtValue::borrowed_value::<RawInput>(
437 input,
438 ))));
439 }
440 Ok(Emit::Forward(SerializeHandle::arena(
441 input.record()?,
442 state,
443 )))
444}
445
446pub(crate) fn serialize_recorded_atom<'a>(
451 atom: &'a Atom<'_>,
452 state: &mut State,
453) -> Result<Emit<'a>, Error> {
454 if let Atom::Ext(ext) = atom
455 && let Some(input) = ext.downcast_value_ref::<RawInput>()
456 {
457 return serialize_input(input, state);
458 }
459 Ok(Emit::Atom(atom.as_borrowed()))
460}
461
462pub struct Raw<'a, F: RawFormat> {
493 input: RawInput<'a>,
494 _format: PhantomData<fn() -> F>,
495}
496
497impl<'a, F: RawFormat> Raw<'a, F> {
498 pub fn new<B: Into<Cow<'a, [u8]>>>(bytes: B) -> Result<Raw<'a, F>, Error> {
502 let bytes = bytes.into();
503 let info = F::info();
504 if info.is_text() && core::str::from_utf8(&bytes).is_err() {
505 return Err(Error::new(ErrorKind::Syntax, "invalid utf-8"));
506 }
507 {
508 let mut driver = DeserializeDriver::from_fn(|_| SinkHandle::null());
509 (info.replay)(&bytes, &mut driver)?;
510 }
511 Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
513 }
514
515 pub fn encode<T: Serialize + ?Sized>(value: &T) -> Result<Raw<'static, F>, Error> {
517 let info = F::info();
518 let bytes = (info.encode)(SerializeRef::new(&value))?;
519 if info.is_text() && core::str::from_utf8(&bytes).is_err() {
520 return Err(Error::new(
521 ErrorKind::InvalidState,
522 "the encoding of a text format is not utf-8",
523 ));
524 }
525 Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
527 }
528
529 fn from_input(input: RawInput<'a>) -> Raw<'a, F> {
530 debug_assert!(input.is::<F>());
531 Raw {
532 input,
533 _format: PhantomData,
534 }
535 }
536
537 pub fn as_bytes(&self) -> &[u8] {
539 &self.input.bytes
540 }
541
542 pub fn is_borrowed(&self) -> bool {
545 matches!(self.input.bytes, Cow::Borrowed(_))
546 }
547
548 pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
552 self.input.replay(sink, state)
553 }
554
555 pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
559 self.input.deserialize()
560 }
561
562 pub fn into_owned(self) -> Raw<'static, F> {
564 Raw::from_input(self.input.into_owned())
565 }
566
567 #[inline(never)]
569 fn from_atom(atom: Atom<'_>, state: &State) -> Result<Raw<'static, F>, Error> {
570 if let Atom::Ext(ref ext) = atom
571 && let Some(input) = ext.downcast_value_ref::<RawInput>()
572 {
573 if input.is::<F>() {
574 return Ok(Raw::from_input(input.clone().into_owned()));
575 }
576 return Raw::encode(&input.record()?);
577 }
578 let mut recording = RecordBuf::new();
579 recording.set_atom(&atom, state);
580 Raw::encode(&recording)
581 }
582}
583
584impl<'de, F: RawFormat> Raw<'de, F> {
585 #[inline(never)]
587 fn from_borrowed_atom(atom: Atom<'de>, state: &State) -> Result<Raw<'de, F>, Error> {
588 if let Atom::Ext(ref ext) = atom {
589 if let Some(input) = unsafe { ext.downcast_value_ref_covariant::<RawInput>() }
591 && input.is::<F>()
592 {
593 return Ok(Raw::from_input(input.clone()));
594 }
595 }
596 Raw::from_atom(atom, state)
597 }
598}
599
600impl<F: TextRawFormat> Raw<'_, F> {
601 pub fn get(&self) -> &str {
603 unsafe { core::str::from_utf8_unchecked(&self.input.bytes) }
605 }
606}
607
608impl<F: RawFormat> Clone for Raw<'_, F> {
609 fn clone(&self) -> Self {
610 Raw::from_input(self.input.clone())
611 }
612}
613
614impl<F: RawFormat> fmt::Debug for Raw<'_, F> {
615 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
616 let mut debug = f.debug_tuple("Raw");
617 debug.field(&self.input.format.id.name);
618 match self.input.as_str() {
619 Some(text) => debug.field(&text),
620 None => debug.field(&self.input.bytes),
621 };
622 debug.finish()
623 }
624}
625
626impl<F: RawFormat> PartialEq for Raw<'_, F> {
628 fn eq(&self, other: &Self) -> bool {
629 self.input.bytes == other.input.bytes
630 }
631}
632
633impl<F: RawFormat> Eq for Raw<'_, F> {}
634
635impl<F: RawFormat> core::hash::Hash for Raw<'_, F> {
636 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
637 self.input.bytes.hash(state)
638 }
639}
640
641impl<F: RawFormat> Serialize for Raw<'_, F> {
644 fn serialize<'a>(value: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
645 serialize_input(&value.input, state)
646 }
647}
648
649impl<'de, 'a, F: RawFormat> Deserialize<'de> for Raw<'a, F> {
653 fn deserialize_into<'out>(
654 out: &'out mut Option<Self>,
655 state: &mut State,
656 ) -> SinkHandle<'out, 'de> {
657 RecordBuf::capture_with(RawCapture(out), state)
658 }
659
660 fn expecting() -> Cow<'static, str> {
661 Cow::Borrowed("any value")
662 }
663
664 #[inline]
665 fn __private_atom_into(
666 out: &mut Option<Self>,
667 atom: Atom,
668 state: &mut State,
669 ) -> Result<(), Error> {
670 *out = Some(Raw::from_atom(atom, state)?);
671 Ok(())
672 }
673
674 #[inline]
675 fn __private_borrowed_atom_into(
676 out: &mut Option<Self>,
677 atom: Atom<'de>,
678 state: &mut State,
679 ) -> Result<(), Error> {
680 *out = Some(Raw::from_atom(atom, state)?);
681 Ok(())
682 }
683
684 #[inline(always)]
685 fn __private_raw() -> Option<&'static RawFormatInfo> {
686 Some(F::info())
687 }
688}
689
690impl<'de: 'a, 'a, F: RawFormat> Deserialize<'de, Raw<'a, F>> for Borrowed {
692 fn deserialize_into<'out>(
693 out: &'out mut Option<Raw<'a, F>>,
694 state: &mut State,
695 ) -> SinkHandle<'out, 'de> {
696 RecordBuf::capture_with(BorrowedRawCapture(out), state)
697 }
698
699 fn expecting() -> Cow<'static, str> {
700 Cow::Borrowed("any value")
701 }
702
703 #[inline]
704 fn __private_atom_into(
705 out: &mut Option<Raw<'a, F>>,
706 atom: Atom,
707 state: &mut State,
708 ) -> Result<(), Error> {
709 *out = Some(Raw::from_atom(atom, state)?);
710 Ok(())
711 }
712
713 #[inline]
714 fn __private_borrowed_atom_into(
715 out: &mut Option<Raw<'a, F>>,
716 atom: Atom<'de>,
717 state: &mut State,
718 ) -> Result<(), Error> {
719 *out = Some(Raw::from_borrowed_atom(atom, state)?);
720 Ok(())
721 }
722
723 #[inline(always)]
724 fn __private_raw() -> Option<&'static RawFormatInfo> {
725 Some(F::info())
726 }
727}
728
729impl<'a, F: RawFormat> Serialize<Raw<'a, F>> for Borrowed {
730 fn serialize<'x>(value: &'x Raw<'a, F>, state: &mut State) -> Result<Emit<'x>, Error> {
731 <Raw<'a, F>>::serialize(value, state)
732 }
733}
734
735struct RawCapture<'o, 'a, F: RawFormat>(&'o mut Option<Raw<'a, F>>);
737
738impl<'o, 'a, 'de, F: RawFormat> Capture<'de, RecordBuf<'de>> for RawCapture<'o, 'a, F> {
739 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
740 *self.0 = Some(Raw::from_atom(atom, state)?);
741 Ok(())
742 }
743
744 fn recorded(&mut self, recording: RecordBuf<'de>, _state: &mut State) -> Result<(), Error> {
745 *self.0 = Some(Raw::encode(&recording)?);
746 Ok(())
747 }
748}
749
750struct BorrowedRawCapture<'o, 'a, F: RawFormat>(&'o mut Option<Raw<'a, F>>);
752
753impl<'o, 'a, 'de: 'a, F: RawFormat> Capture<'de, RecordBuf<'de>> for BorrowedRawCapture<'o, 'a, F> {
754 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
755 *self.0 = Some(Raw::from_atom(atom, state)?);
756 Ok(())
757 }
758
759 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
760 *self.0 = Some(Raw::from_borrowed_atom(atom, state)?);
761 Ok(())
762 }
763
764 fn recorded(&mut self, recording: RecordBuf<'de>, _state: &mut State) -> Result<(), Error> {
765 *self.0 = Some(Raw::encode(&recording)?);
766 Ok(())
767 }
768}