Skip to main content

deser_core/ext/
raw.rs

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
16/// A data format whose encoded values can be held by [`Raw`].
17///
18/// This is implemented by a type of the crate of the format that stands
19/// for the format (for instance `deser_json::Json`).  The format is
20/// described at runtime by a [`RawFormatInfo`].
21///
22/// # Passing on the Input of Values
23///
24/// Raw values of a format that is deserialized from the same format hold
25/// the input of the value, and serializers of the format write them as
26/// they are.  For this the format:
27///
28/// * calls [`State::declare_raw_format`](crate::State::declare_raw_format) with
29///   its [`RawFormatId`] in the deserializer (before the first event, it
30///   returns the description of the format if the top-level value is
31///   wanted as raw value) and in the serializer (before the first value).
32/// * checks with [`Error::is_raw_request`](crate::Error::is_raw_request)
33///   whether the result of an event requests the next value as raw value
34///   and takes the description of the format with
35///   [`State::take_raw_request`](crate::State::take_raw_request).
36/// * checks that the description has the [`RawFormatId`] of the format
37///   (requests can be for raw values of any format, they are an error
38///   then), validates a value that is wanted as raw value and emits its
39///   input as [`RawInput`] (an [`Atom::Ext`]) with that description
40///   rather than its events.
41/// * writes the [`RawInput`] of its format as it is when serializing
42///   (see [`RawInput::is_format`]).
43///
44/// The parser and the serializer only refer to the [`RawFormatId`]: the
45/// functions of the format (like `replay`, which brings in its parser)
46/// are only in programs that use its raw values.
47///
48/// Formats that do not do this still have raw values: the values are
49/// encoded with the format then.
50pub trait RawFormat: 'static {
51    /// Returns the description of the format.
52    ///
53    /// This must always return the same static: formats are identified by
54    /// the address of their description.
55    fn info() -> &'static RawFormatInfo;
56}
57
58/// A [`RawFormat`] whose encoding is text.
59///
60/// [`Raw`] values of such formats can be accessed as strings (see
61/// [`Raw::get`]).
62///
63/// # Safety
64///
65/// The format must be described as text (see [`RawFormatId::new`]): its
66/// parser only passes on and its encoder only produces valid UTF-8.
67pub unsafe trait TextRawFormat: RawFormat {}
68
69/// Identifies a [`RawFormat`].
70///
71/// Formats are identified by the address of a static of this type.  Unlike
72/// the [`RawFormatInfo`] of the format it holds no functions: formats
73/// declare which raw values they pass on with it (see
74/// [`State::declare_raw_format`](crate::State::declare_raw_format)), so a program
75/// only contains the functions of the format (like its parser for
76/// `replay`) if it uses its raw values.
77pub struct RawFormatId {
78    name: &'static str,
79    is_text: bool,
80}
81
82impl RawFormatId {
83    /// Creates the identity of a format.
84    ///
85    /// * `name` is the name of the format (like `"json"`).
86    /// * `is_text` is `true` if the encoding is text.  The encoded values
87    ///   must then be valid UTF-8.
88    pub const fn new(name: &'static str, is_text: bool) -> RawFormatId {
89        RawFormatId { name, is_text }
90    }
91
92    /// Returns the name of the format.
93    pub fn name(&self) -> &'static str {
94        self.name
95    }
96
97    /// Returns `true` if the encoding of the format is text.
98    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
111/// Describes a [`RawFormat`] at runtime.
112///
113/// Formats that can pass on the input of values define a static of this
114/// type.  It travels with the input of values (see [`RawInput`]) so that
115/// code which does not know the format can still parse it.  Formats are
116/// identified by their [`RawFormatId`].
117pub 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    /// Creates the description of a format.
128    ///
129    /// * `id` identifies the format.
130    /// * `replay` parses a value and emits its events into the driver.
131    /// * `encode` encodes a value.
132    /// * `fallback` returns the fallback atom of an encoded value (see
133    ///   [`Extension::fallback`](crate::ext::Extension::fallback)).  It
134    ///   must be [`Atom::Null`] for null, so that optionals are `None` for
135    ///   it, and must not be an extension value.
136    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    /// Attaches data of the format to the description.
153    ///
154    /// The format gets it back from the description of raw values that are
155    /// requested (see [`data`](Self::data)).  Formats keep what only
156    /// programs that use their raw values need here (like the scanner of
157    /// raw values in the parser): as only raw values refer to the
158    /// description, other programs do not contain it.
159    pub const fn set_data(&mut self, data: &'static (dyn Any + Send + Sync)) {
160        self.data = Some(data);
161    }
162
163    /// Installs a scanner that checks limits without interpreting raw data.
164    #[doc(hidden)]
165    pub const fn set_check_limits(&mut self, check: CheckRawLimits) {
166        self.check_limits = Some(check);
167    }
168
169    /// Returns the data of the format (see [`set_data`](Self::set_data)).
170    pub fn data(&self) -> Option<&'static (dyn Any + Send + Sync)> {
171        self.data
172    }
173
174    /// Returns the identity of the format.
175    pub fn id(&self) -> &'static RawFormatId {
176        self.id
177    }
178
179    /// Returns the name of the format.
180    pub fn name(&self) -> &'static str {
181        self.id.name
182    }
183
184    /// Returns `true` if the encoding of the format is text.
185    pub fn is_text(&self) -> bool {
186        self.id.is_text
187    }
188
189    /// Records an encoded value.
190    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/// Returns `true` if two descriptions are the same format.
207#[inline(always)]
208fn same_format(a: &'static RawFormatInfo, b: &'static RawFormatInfo) -> bool {
209    core::ptr::eq(a.id, b.id)
210}
211
212/// The encoded input of a value.
213///
214/// This is a well-known borrowing extension (see [`ext`](crate::ext)) which
215/// carries the encoding of a value between formats and [`Raw`] values:
216///
217/// * formats emit it for values that are requested as raw values (the
218///   values of [`Raw`] types).  They validate the value and pass on its
219///   input instead of its events.
220/// * [`Raw`] values emit it when they are serialized and the serializer
221///   writes the format as it is (see [`State::declare_raw_format`]).
222///
223/// It knows its format, so it's parsed into its value where it ends up in
224/// something that does not know it (for instance when a recording that
225/// holds it is serialized).
226#[derive(Clone)]
227pub struct RawInput<'a> {
228    bytes: Cow<'a, [u8]>,
229    format: &'static RawFormatInfo,
230}
231
232impl<'a> RawInput<'a> {
233    /// Creates the input of a value.
234    ///
235    /// # Safety
236    ///
237    /// The input must be a single, valid value of the format.  If the
238    /// format is text, it must be valid UTF-8.  Serializers of the format
239    /// write the input as it is.
240    ///
241    /// Descriptions of formats can be created by anybody (with the
242    /// identity of any format) and requests for raw values can be for any
243    /// format: formats must check that the description has the identity
244    /// of their own format (see
245    /// [`State::take_raw_request`](crate::State::take_raw_request)) rather
246    /// than rely on where it comes from or on its
247    /// [`data`](RawFormatInfo::data).
248    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    /// Returns the encoded value.
258    pub fn as_bytes(&self) -> &[u8] {
259        &self.bytes
260    }
261
262    /// Returns the encoded value as text if the format is text.
263    pub fn as_str(&self) -> Option<&str> {
264        // SAFETY: the input of text formats is valid UTF-8, see `new`
265        self.format
266            .is_text()
267            .then(|| unsafe { core::str::from_utf8_unchecked(&self.bytes) })
268    }
269
270    /// Returns the format of the value.
271    pub fn format(&self) -> &'static RawFormatInfo {
272        self.format
273    }
274
275    /// Returns `true` if the value is of the format `F`.
276    pub fn is<F: RawFormat>(&self) -> bool {
277        same_format(self.format, F::info())
278    }
279
280    /// Returns `true` if the value is of the format with the identity.
281    ///
282    /// Serializers check with this whether they write a value as it is
283    /// (unlike [`is`](Self::is), this does not refer to the functions of
284    /// the format).
285    pub fn is_format(&self, id: &'static RawFormatId) -> bool {
286        core::ptr::eq(self.format.id, id)
287    }
288
289    /// Detaches the input from the data it borrows.
290    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    /// Records the value.
298    pub fn record(&self) -> Result<RecordBuf<'_>, Error> {
299        self.format.record(&self.bytes)
300    }
301
302    /// Replays the value into a sink.
303    ///
304    /// The value is parsed, the sink can borrow its data.
305    pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
306        // the type of the sink is unknown, it does not want a raw value
307        self.replay_raw(sink, None, state)
308    }
309
310    /// Replays the value, `raw` is the raw value the sink wants.
311    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            // the top-level value is requested before it starts
319            driver.state_mut().raw_requested = raw;
320            (self.format.replay)(&self.bytes, driver)
321        })
322    }
323
324    /// Checks limits on the encoded contents, not on the opaque extension atom.
325    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        // Scanner offsets refer to the raw input, not the enclosing stream.
337        // Let the outer driver attach the location and context of the raw value.
338        result.map_err(|err| Error::new(err.kind(), err.message().to_owned()))
339    }
340
341    /// Deserializes the value.
342    ///
343    /// The value can borrow from the input (and the data it borrows).
344    pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
345        // the driver requests the value as raw value if `T` wants one
346        crate::de::deserialize_value(|driver| (self.format.replay)(&self.bytes, driver))
347    }
348}
349
350/// Parses the input of a raw value into a sink that does not accept it.
351///
352/// The sink is finished by the caller (see `NoFinish`).
353pub(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        // the input lives shorter than the data of the sink
362        driver.transient(|driver| (input.format.replay)(&input.bytes, driver))
363    })
364}
365
366/// Counts the events of formats without a dedicated raw limit scanner.
367struct 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
409/// Forwards to a sink except for [`Sink::finish`].
410///
411/// This is used to parse a value into a sink that received an atom (see
412/// `parse_into`): the replay finishes the value, the sink is finished by
413/// the code that delivered the atom.
414struct 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
500/// Serializes the input of a value.
501///
502/// The input is passed on as extension value if the serializer writes its
503/// format as it is, otherwise the value is parsed and serialized.
504fn 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
516/// Serializes an atom of a recording.
517///
518/// The input of values that the serializer does not write as it is is
519/// parsed and serialized.
520pub(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
532/// A value encoded in the format `F`.
533///
534/// A raw value holds a value in the encoding of a format, for instance
535/// JSON text with `deser_json::RawJson`.  It can be deserialized later
536/// (with [`deserialize`](Self::deserialize)), stored or written out again
537/// unchanged:
538///
539/// * If it's deserialized from the format `F`, it holds the input of the
540///   value as it is.  The format only validates the value and does not
541///   produce its events, which is fast.  With the
542///   [`Borrowed`] adapter the input is
543///   borrowed.
544/// * Otherwise (from another format or where the format cannot pass on
545///   the input, see below) the value is encoded in the format `F`.  The
546///   encoding can lose information that `F` cannot express (bytes in JSON
547///   for instance).  To keep a value of any format without interpreting
548///   it, use [`Recording`](crate::de::Recording).
549///
550/// When serialized with the format `F`, the encoded value is written as it
551/// is.  Other formats serialize the value it holds.
552///
553/// The input of values can only be passed on if the format knows before
554/// the value starts that a raw value is wanted.  Derived structs (for their
555/// first 64 fields), maps, sequences, `Option` and `Box` ask for it.
556/// Values in other places (like the fields of flattened structs, the
557/// variants of enums and values that are buffered, for instance for
558/// untagged enums) are encoded.
559///
560/// Like `Cow`, raw values are deserialized owned, so a `Raw<'static, F>`
561/// can be deserialized from any data.
562pub struct Raw<'a, F: RawFormat> {
563    input: RawInput<'a>,
564    _format: PhantomData<fn() -> F>,
565}
566
567impl<'a, F: RawFormat> Raw<'a, F> {
568    /// Creates a raw value from its encoding.
569    ///
570    /// The value is validated.
571    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        // SAFETY: the value was validated
582        Ok(Raw::from_input(unsafe { RawInput::new(bytes, info) }))
583    }
584
585    /// Encodes a value.
586    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        // SAFETY: the encoder produces a valid value
596        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    /// Returns the encoded value.
608    pub fn as_bytes(&self) -> &[u8] {
609        &self.input.bytes
610    }
611
612    /// Returns `true` if the value borrows from the data it was
613    /// deserialized from.
614    pub fn is_borrowed(&self) -> bool {
615        matches!(self.input.bytes, Cow::Borrowed(_))
616    }
617
618    /// Replays the value into a sink.
619    ///
620    /// The value is parsed, the sink can borrow its data.
621    pub fn replay<'x>(&'x self, sink: SinkHandle<'_, 'x>, state: &mut State) -> Result<(), Error> {
622        self.input.replay(sink, state)
623    }
624
625    /// Deserializes the value.
626    ///
627    /// The value can borrow from the raw value (and the data it borrows).
628    pub fn deserialize<'x, T: Deserialize<'x>>(&'x self) -> Result<T, Error> {
629        self.input.deserialize()
630    }
631
632    /// Detaches the value from the data it borrows.
633    pub fn into_owned(self) -> Raw<'static, F> {
634        Raw::from_input(self.input.into_owned())
635    }
636
637    /// Creates a raw value from an atom that was delivered for it.
638    #[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    /// Creates a raw value from an atom that was delivered borrowed for it.
656    #[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            // SAFETY: raw inputs are covariant in their lifetime
660            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    /// Returns the encoded value as text.
672    pub fn get(&self) -> &str {
673        // SAFETY: the encoding of text formats is valid UTF-8
674        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
696/// Raw values are equal if their encodings are equal.
697impl<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
711/// Serialized with the format `F`, the encoded value is written as it is.
712/// Other formats serialize the value it holds.
713impl<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
719/// Raw values are deserialized owned so that `Raw<'static, F>` can be
720/// deserialized from any data.  To borrow use the
721/// [`Borrowed`] adapter.
722impl<'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
760/// Borrows raw values from the data if the format passes it on borrowed.
761impl<'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
805/// Places a captured value into the slot of a raw value, owned.
806struct 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
820/// Places a captured value into the slot of a raw value, borrowed.
821struct 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}