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
/// Iteration item for option values
///
/// An implementation needs to allow the user to get the value as a memory slice. This is trivial
/// for messages that are stored in serialized form. Implementations that store options
/// semantically (eg. as a `struct Block { n: usize, m: bool, szx: u8 }`) will typically make their
/// MessageOption large enough to contain serialized options, or heap-allocate for them.
/// Marker trait that indicates that ReadableMessage::options are produced in ascending
/// sequence.
// It would be nice to have more type state in here (for headers, last option number and whether
// payload has been set); this is a first step that can easily wrap jnet and maybe gcoap. Taking
// the next step is likely to happen soon, given that jnet coap has already moved to type state.
/// A message that needs to have its code, any options in ascending order and its payload set in
/// that very sequence.
///
/// This is the bare minimum a message needs to provide to be populated as a request or response by
/// a generic program; it is up to the program to ensure the valid sequence of operations, as
/// failure to do so may incur panics (FIXME: or errors).
/// A message that allows later manipulation of a once set payload, and later truncation.
///
/// This is a bit of an unsorted bag that needs further cleanup (FIXME) -- most of this is
/// motivated by block-wise and write-in-place. Might need a bit of reshape, possibly something
/// like a once-callable ``.write_payload(|d: &mut [u8]| { write_to(d); Ok(bytes_written)})``. Does
/// this need a hint of the length to allocate for implementations that don't pre-allocate the
/// message? Is 1024 a good enough value to not pass it?
///
/// The available_space is only needed where applications want to use up the last byte by not
/// zero-padding the Block2 option to its szx=0 equivalent.
///
/// Can that be efficiently be replaced with something like this, and can it be optimized down to
/// the hand-written counting-of-option-bytes that's involved in the use of available_space?
///
/// ```ignore
/// let mut m = allocated_message;
/// for szx in 6..0 {
/// snap = m.snapshot();
/// m.add_option(BLOCK2, ...);
/// m.add_option(..., ...);
///
/// if let Ok(_) = m.write_payload(|p| {
/// if (p.len() < 1 << (4 + szx)) {
/// return Err(());
/// }
///
/// let written = write_block(...);
///
/// Ok(written)
/// }) {
/// break;
/// } else {
/// m = m.revert_to(snap);
/// }
/// } else {
/// panic!("Allocated space doesn't even suffice for 16 byte payload");
/// }
/// ```
///