musli_core/de/
unsized_visitor.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use core::borrow::Borrow;
use core::fmt;
use core::marker::PhantomData;

use crate::expecting::{self, Expecting};
use crate::no_std::ToOwned;
use crate::Context;

/// A visitor for data where we might need to borrow without copying from the
/// underlying [`Decoder`].
///
/// A visitor is needed with [`Decoder::decode_bytes`] and
/// [`Decoder::decode_string`] because the caller doesn't know if the encoding
/// format is capable of producing references to the underlying data directly or
/// if it needs to be processed first.
///
/// If all you want is to decode a value by reference, use the
/// [`Decoder::decode_unsized`] method.
///
/// By requiring a visitor we ensure that the caller has to handle both
/// scenarios, even if one involves erroring. A type like [Cow] is an example of
/// a type which can comfortably handle both.
///
/// [Cow]: std::borrow::Cow
/// [`Decoder`]: crate::de::Decoder
/// [`Decoder::decode_bytes`]: crate::de::Decoder::decode_bytes
/// [`Decoder::decode_string`]: crate::de::Decoder::decode_string
/// [`Decoder::decode_unsized`]: crate::de::Decoder::decode_unsized
pub trait UnsizedVisitor<'de, C: ?Sized + Context, T>: Sized
where
    T: ?Sized + ToOwned,
{
    /// The value produced.
    type Ok;

    /// Format an error indicating what was expected by this visitor.
    ///
    /// Override to be more specific about the type that failed.
    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;

    /// Visit an owned value.
    #[inline]
    fn visit_owned(self, cx: &C, value: T::Owned) -> Result<Self::Ok, C::Error> {
        self.visit_ref(cx, value.borrow())
    }

    /// Visit a string that is borrowed directly from the source data.
    #[inline]
    fn visit_borrowed(self, cx: &C, value: &'de T) -> Result<Self::Ok, C::Error> {
        self.visit_ref(cx, value)
    }

    /// Visit a value reference that is provided from the decoder in any manner
    /// possible. Which might require additional decoding work.
    #[inline]
    fn visit_ref(self, cx: &C, _: &T) -> Result<Self::Ok, C::Error> {
        Err(cx.message(expecting::bad_visitor_type(
            &expecting::AnyValue,
            ExpectingWrapper::new(&self),
        )))
    }
}

#[repr(transparent)]
struct ExpectingWrapper<'a, T, C: ?Sized, I: ?Sized> {
    inner: T,
    _marker: PhantomData<(&'a C, &'a I)>,
}

impl<'a, T, C: ?Sized, U: ?Sized> ExpectingWrapper<'a, T, C, U> {
    #[inline]
    fn new(value: &T) -> &Self {
        // SAFETY: `ExpectingWrapper` is repr(transparent) over `T`.
        unsafe { &*(value as *const T as *const Self) }
    }
}

impl<'a, 'de, T, C, U> Expecting for ExpectingWrapper<'a, T, C, U>
where
    T: UnsizedVisitor<'de, C, U>,
    C: ?Sized + Context,
    U: ?Sized + ToOwned,
{
    #[inline]
    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.inner.expecting(f)
    }
}