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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! Compile fail tests.
/// ```compile_fail
/// # #[cfg(all(feature = "derive", feature = "alloc"))] {
/// use wincode::{SchemaRead, SchemaWrite, deserialize, serialize};
///
/// #[derive(SchemaRead, SchemaWrite)]
/// struct StaticStr {
/// value: Option<&'static str>,
/// }
///
/// let serialized = serialize(&StaticStr {
/// value: Some("actually static"),
/// })
/// .unwrap();
///
/// let _: StaticStr = deserialize(&serialized).unwrap();
/// # }
/// ```
///
/// ```
/// # #[cfg(all(feature = "derive"))] {
/// use wincode::{SchemaRead, SchemaWrite, deserialize};
///
/// #[derive(SchemaRead, SchemaWrite)]
/// struct StaticStr {
/// value: Option<&'static str>,
/// }
///
/// let serialized = b"\x00".as_slice();
///
/// let _: StaticStr = deserialize(serialized).unwrap();
/// # }
/// ```
/// ```compile_fail
/// # #[cfg(all(feature = "derive"))] {
/// use wincode::{SchemaRead, SchemaWrite};
///
/// #[derive(SchemaRead, SchemaWrite)]
/// enum MyEnum {
/// #[wincode(tag = 1)]
/// Foo,
/// #[wincode(tag = 1)]
/// Bar,
/// }
/// # }
/// ```
/// ```compile_fail
/// # #[cfg(all(feature = "derive"))] {
/// use wincode::{SchemaRead, SchemaWrite};
///
/// #[derive(SchemaRead, SchemaWrite)]
/// enum MyEnum {
/// #[wincode(tag = 1)]
/// Foo,
/// #[wincode(tag = 0x1)]
/// Bar,
/// }
/// # }
/// ```
/// ```compile_fail
/// # #[cfg(all(feature = "derive"))] {
/// use wincode::{SchemaRead, SchemaWrite};
///
/// #[derive(SchemaRead, SchemaWrite)]
/// enum MyEnum {
/// Foo,
/// #[wincode(tag = 0)]
/// Bar,
/// }
/// # }
/// ```
/// A `read_<field>` on an `UninitBuilder` must not launder the reader lifetime: reading
/// from a short-lived reader into a longer-lived borrowed field (here `'static`) would
/// leave a dangling reference after `assume_init`.
///
/// ```compile_fail
/// # #[cfg(all(feature = "derive"))] {
/// use {core::mem::MaybeUninit, wincode::config::DefaultConfig};
///
/// #[derive(wincode::UninitBuilder)]
/// struct Borrowed<'a> {
/// data: &'a [u8],
/// }
///
/// fn launder() -> Borrowed<'static> {
/// let mut uninit = MaybeUninit::<Borrowed<'static>>::uninit();
/// {
/// let short_lived: Vec<u8> = vec![3, 0, 0, 0, 0, 0, 0, 0, 0xAA, 0xBB, 0xCC];
/// let mut builder =
/// BorrowedUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
/// builder.read_data(short_lived.as_slice()).unwrap();
/// builder.finish();
/// }
/// unsafe { uninit.assume_init() }
/// }
/// # }
/// ```
/// An `UninitBuilder` reader must write exactly the field type, even when the field's
/// `SchemaRead` implementation declares a different `Dst`.
///
/// ```compile_fail
/// # #[cfg(all(feature = "derive"))] {
/// use {
/// core::mem::MaybeUninit,
/// wincode::{
/// ReadResult, SchemaRead,
/// config::{ConfigCore, DefaultConfig},
/// io::Reader,
/// },
/// };
///
/// struct Field;
/// struct DifferentDst(u64);
///
/// unsafe impl<'de, C: ConfigCore> SchemaRead<'de, C> for Field {
/// type Dst = DifferentDst;
///
/// fn read(
/// _reader: impl Reader<'de>,
/// dst: &mut MaybeUninit<Self::Dst>,
/// ) -> ReadResult<()> {
/// dst.write(DifferentDst(0));
/// Ok(())
/// }
/// }
///
/// #[derive(wincode::UninitBuilder)]
/// struct HasField {
/// field: Field,
/// }
///
/// let mut uninit = MaybeUninit::<HasField>::uninit();
/// let mut builder =
/// HasFieldUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
/// builder.read_field([].as_slice()).unwrap();
/// # }
/// ```