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
//! Derive macros for `SchemaWrite` and `SchemaRead`.
//!
//! Note using this on packed structs is UB.
//!
//! Refer to the [`wincode`](https://docs.rs/wincode) crate for examples.
use ;
/// Implement `SchemaWrite` for a struct or enum.
/// Implement `SchemaRead` for a struct or enum.
///
/// When the type has `#[wincode(context = "ContextType")]`, this implements
/// `SchemaReadContext` instead. Fields marked with `#[wincode(context)]` receive
/// that context; unmarked fields continue to use `SchemaRead`.
///
/// See the `wincode` crate's derive-attribute documentation for details and examples.
/// Include placement initialization helpers for structs.
///
/// This generates an `UninitBuilder` for the given struct, providing convenience
/// methods that can avoid a lot of boilerplate when implementing custom
/// `SchemaRead` implementations. In particular, it provides methods that
/// deal with projecting subfields of structs into `MaybeUninit`s. Without this,
/// one would have to write a litany of `&mut *(&raw mut (*dst_ptr).field).cast()` to
/// access MaybeUninit struct fields. It also provides initialization helpers and
/// drop tracking logic.
///
/// For example:
/// ```ignore
/// #[derive(UninitBuilder)]
/// struct Message {
/// payload: Vec<u8>,
/// bytes: [u8; 32],
/// }
///
/// unsafe impl<'de, C: Config> SchemaRead<'de, C> for Message {
/// type Dst = Self;
///
/// fn read(mut reader: impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
/// let msg_builder = MessageUninitBuilder::<C>::from_maybe_uninit_mut(dst);
/// // Deserializes a `Vec<u8>` into the `payload` slot of `Message` and marks the field
/// // as initialized. If the subsequent `read_bytes` call fails, the `payload` field will
/// // be dropped.
/// msg_builder.read_payload(reader.by_ref())?;
/// msg_builder.read_bytes(reader)?;
/// msg_builder.finish();
/// }
/// }
/// ```
///
/// We cannot do this for enums, given the lack of facilities for placement initialization.