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
151
152
153
154
155
156
//! Break-condition types and trait for controlling the KLV field-decoding loop
//!
//! The derive-generated `decode_value` implementation loops over key-length-value
//! triples. After each key and length are decoded, [`BreakCondition::break_condition`]
//! is called to let the type decide what to do next. The return value is one
//! of four [`BreakConditionType`] variants that map directly to control-flow
//! actions inside the loop.
//!
//! Most types accept the default blanket implementation (always [`BreakConditionType::Proceed`]);
//! implement [`BreakCondition`] explicitly only when custom early-exit or skip
//! logic is needed.
//!
//! Author: aav
// --------------------------------------------------
// external
// --------------------------------------------------
use ContextError;
/// The four possible outcomes of a per-field break-condition check in the decode loop
///
/// Returned by [`BreakCondition::break_condition`] after each key and length
/// are parsed. The derive-generated loop branches on this value to decide
/// whether to decode the field, skip it, return early, or abort with an error.
/// Allows a type to inspect each decoded key and length and control the decode loop
///
/// The derive macro calls [`BreakCondition::break_condition`] inside the
/// field-dispatch loop after every key and length decode. The default
/// implementation always returns [`BreakConditionType::Proceed`], which is
/// correct for the vast majority of types.
///
/// Override this method to:
/// * skip unrecognised tags ([`BreakConditionType::Skip`])
/// * stop early when a sentinel tag is seen ([`BreakConditionType::Done`])
/// * abort with a hard error on an impossible length ([`BreakConditionType::Abort`])
///
/// # Arguments
///
/// * `decoded_key` - The tag/key value just decoded from the stream
/// * `decoded_len` - The length value just decoded from the stream
///
/// # Returns
///
/// A [`BreakConditionType`] directing the decode loop how to proceed
/// [`BreakCondition`] blanket implementation for all types `T` that implement [`DecodeValue`]
///
/// Provides the default "always proceed" behaviour for every type that can
/// be decoded. Override [`BreakCondition::break_condition`] on the concrete
/// type when custom loop-control logic is required.