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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! Compile tests for soundness issues that were fixed. These are only
//! compiled as doctests.
/// A driver must not outlive the sink it drives.
///
/// ```compile_fail,E0597
/// use deser::de::DeserializeDriver;
/// use deser::Deserialize;
///
/// let mut driver = {
/// let mut out = None::<Vec<u32>>;
/// DeserializeDriver::from_fn(|state| {
/// Vec::<u32>::deserialize_into(&mut out, state)
/// })
/// };
/// driver.emit(1u64).unwrap();
/// ```
///
/// The sink held by an owned sink cannot be replaced.
///
/// ```compile_fail,E0277
/// use deser::de::{OwnedSink, SinkHandle};
/// use deser::{Deserialize, State};
///
/// let mut state = State::new();
/// let mut owned = OwnedSink::<u32>::deserialize(&mut state);
/// let mut local = None::<u32>;
/// *owned.get_mut() =
/// u32::deserialize_into(&mut local, &mut state);
/// ```
///
/// Borrowed extensions have to prove that their values can be shortened.
/// For types that are not covariant, the trivial implementation does not
/// compile.
///
/// ```compile_fail
/// use std::sync::Mutex;
/// use deser::ext::BorrowedExtension;
/// use deser::Atom;
///
/// #[derive(Debug)]
/// pub struct Invariant<'a>(pub Mutex<&'a str>);
///
/// impl PartialEq for Invariant<'_> {
/// fn eq(&self, _other: &Self) -> bool {
/// true
/// }
/// }
///
/// impl BorrowedExtension for Invariant<'static> {
/// type Value<'a> = Invariant<'a>;
/// fn name<'v>(_value: &'v Invariant<'_>) -> &'v str {
/// "invariant"
/// }
/// fn fallback<'v>(_value: &'v Invariant<'_>) -> Atom<'v> {
/// Atom::Null
/// }
/// fn to_static(_value: &Invariant<'_>) -> Invariant<'static> {
/// Invariant(Mutex::new(""))
/// }
/// fn shorten<'s, 'l: 's>(
/// value: &'s Invariant<'l>,
/// ) -> &'s Invariant<'s> {
/// value
/// }
/// }
/// ```
///
/// Values of borrowed extensions cannot escape the extension value.
///
/// ```compile_fail,E0515
/// # use std::borrow::Cow;
/// # use deser::ext::BorrowedExtension;
/// # use deser::Atom;
/// # #[derive(Debug, Clone, PartialEq)]
/// # pub struct Literal<'a>(Cow<'a, str>);
/// # impl BorrowedExtension for Literal<'static> {
/// # type Value<'a> = Literal<'a>;
/// # fn name<'v>(_value: &'v Literal<'_>) -> &'v str { "literal" }
/// # fn fallback<'v>(value: &'v Literal<'_>) -> Atom<'v> { Atom::Str(Text::borrowed(&value.0)) }
/// # fn to_static(value: &Literal<'_>) -> Literal<'static> { Literal(Cow::Owned(value.0.to_string())) }
/// # fn shorten<'s, 'l: 's>(value: &'s Literal<'l>) -> &'s Literal<'s> { value }
/// # }
/// use deser::ext::ExtValue;
///
/// fn leak<'a>(ext: ExtValue<'a>) -> &'a Literal<'a> {
/// ext.downcast_value_ref::<Literal>().unwrap()
/// }
/// ```
///
/// Extension values cannot outlive the data they borrow.
///
/// ```compile_fail,E0597
/// # use std::borrow::Cow;
/// # use deser::ext::BorrowedExtension;
/// # use deser::Atom;
/// # #[derive(Debug, Clone, PartialEq)]
/// # pub struct Literal<'a>(Cow<'a, str>);
/// # impl BorrowedExtension for Literal<'static> {
/// # type Value<'a> = Literal<'a>;
/// # fn name<'v>(_value: &'v Literal<'_>) -> &'v str { "literal" }
/// # fn fallback<'v>(value: &'v Literal<'_>) -> Atom<'v> { Atom::Str(Text::borrowed(&value.0)) }
/// # fn to_static(value: &Literal<'_>) -> Literal<'static> { Literal(Cow::Owned(value.0.to_string())) }
/// # fn shorten<'s, 'l: 's>(value: &'s Literal<'l>) -> &'s Literal<'s> { value }
/// # }
/// use deser::ext::ExtValue;
///
/// let ext = {
/// let text = String::from("1.5");
/// ExtValue::owned_value::<Literal>(Literal(Cow::Borrowed(&text)))
/// };
/// drop(ext);
/// ```
;