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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! Convenience interfaces for common decoding patterns.
//!
//! The functions in this module are suited to decoding records from files and
//! data slices, publishing to the [`FromRecords`] and [`FromRecord`] traits.
//!
//! In many cases (when records are of a known shape), these traits can be
//! derived. See the [`FromRecords`](macro@FromRecords) and
//! [`FromRecord`](macro@FromRecord) macros for details.
pub use decode as decode_reader;
pub use decode as decode_slice;
/// Derive [`FromRecords`] for a struct holding a collection of records.
///
/// _Requires Cargo feature `derive`._
///
/// # Example
///
/// To collect a single record, add the `record(N)` attribute to an `Option<T>`
/// struct field, where `N` is the global message number and `T` is a type
/// implementing [`Record`] and [`Default`]. Additional records received for the
/// same message number will overwrite earlier ones. To collect multiple
/// occurrences of a record, apply the attribute to a `Vec<T>` instead.
///
/// ```
/// #[derive(Debug, Default, FromRecords)]
/// struct ActivityRecordSet {
/// #[record(0)]
/// file_id: Option<FileId>,
/// #[record(20)]
/// records: Vec<Record>,
/// }
/// ```
pub use FromRecords;
/// Produce record receivers for a document.
///
/// See the [`FromRecords`](macro@FromRecords) derive macro for an automatic
/// implementation of this trait.
/// Derive [`FromRecord`] for a struct representing a single record.
///
/// _Requires Cargo feature `derive`._
///
/// # Examples
///
/// To receive a single value for a record field, add the `field(N)` attribute
/// to an `Option<T>` struct field, where `N` is the field number and `T` is the
/// corresponding Rust primitive. Additional values received for the same field
/// will replace earlier ones.
///
/// To receive the time offset stored in compressed timestamp headers, supply
/// `time` in place of a field number.
///
/// ```
/// #[derive(Debug, Default, FromRecord)]
/// struct Record {
/// #[field(time)]
/// time_offset: Option<u8>,
/// #[field(0)]
/// position_lat: Option<i32>,
/// #[field(1)]
/// position_long: Option<i32>,
/// #[field(2)]
/// altitude: Option<u16>,
/// }
/// ```
///
/// Rather than decoding directly into domain types, it's recommended to store
/// the received primitives and process them afterward in an accessor.
///
/// ```
/// impl Record {
/// fn position(&self) -> Option<(f32, f32)> {
/// if let (Some(lat), Some(long)) = (self.position_lat, self.position_long) {
/// // Convert from the stored integers to floating point degrees.
/// let lat = (lat as f32 * 180.0) / (i32::MAX as f32);
/// let long = (long as f32 * 180.0) / (i32::MAX as f32);
///
/// Some(Coordinate {
/// latitude_deg: lat,
/// longitude_deg: long,
/// })
/// } else {
/// None
/// }
/// }
/// }
/// ```
///
/// To receive arrays or arbitrary types (for example, decoding directly into an
/// enumeration), supply an accumulator closure. Since the element type cannot
/// be inferred, the second argument must be typed.
///
/// ```
/// #[derive(Debug, Default, FromRecord)]
/// struct Course {
/// #[field(5, |v, c: u8| v.push(c))]
/// name: Option<Vec<u8>>,
/// }
/// ```
///
/// Keep in mind that a UTF-8 string cannot be built byte-by-byte, as a single
/// Unicode code point can span multiple bytes. Instead, collect into a buffer,
/// and convert this buffer later.
///
/// ```
/// impl Course {
/// fn name(&self) -> Option<&str> {
/// self.name
/// .as_ref()
/// .and_then(|v| std::str::from_utf8(v).ok())
/// }
/// }
/// ```
pub use FromRecord;
/// Receive field values for a record.
///
/// Before publishing, fields are converted to their corresponding Rust
/// primitive, and those holding the 'invalid' marker value are skipped. Array
/// types (including strings) are published item-by-item, calling the receiver
/// repeatedly.
///
/// The default implementation of each method ignores received values.
///
/// See the [`FromRecord`](macro@FromRecord) derive macro for an automatic
/// implementation of this trait.