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
use Vec;
use Result;
use slice;
///
/// Defines a method to extend a vector whose additional slots are
/// filled by the specified closure.
///
/// Trait `PushBulk` would be useful when reading data from a file or
/// a stream into a vector, especially when the data size is not known
/// at compile time.
///
/// Method `push_bulk` reserves capacity for at least additional more
/// elements and calls a closure to fill the additional slots, then
/// extends the length of the vector to expose the additional
/// elements. The callee closure receives additional elements as a
/// slice of uninitialized elements. It must fill all elements to
/// avoid exposing uninitialized slots.
///
/// Method `push_bulk` returns the same result returned by the
/// closure. If the closure returns `Err`(), the vector is not
/// extended.
///
/// In typical use cases, method `push_bulk` would be called for an
/// empty vector to fill with data. In some cases, it might be called
/// repeatedly for the same vector to fill with a series of data
/// (e.g. due to some API limitations).
///
/// Trait `PushBulk` is used internally in this crate.
///
/// # Example
///
/// In the example below, method `push_bulk` reads data from
/// `io::Cursor`s into a vector. Method `push_bulk` is called four
/// times as if method `read_exact` had some API limitations. The
/// initial capacity of the vector is set to 16 to avoid unexpected
/// copying.
///
/// ```
/// use std::io::{Cursor, Read};
/// use castflip::experimental::PushBulk;
///
/// // Input data 1 (6 bytes)
/// let bytes1: [u8; 16] = [
/// 0x10, 0x11, 0x12, 0x13,
/// 0x20, 0x21, 0x22, 0x23,
/// 0x30, 0x31, 0x32, 0x33,
/// 0x40, 0x41, 0x42, 0x43,
/// ];
/// let mut input1 = Cursor::new(bytes1);
///
/// // Prepare an empty vector `vec2` with capacity = 16.
/// let mut vec2 = Vec::with_capacity(16);
///
/// // Fill the vector with loaded data.
/// for i in 0 .. 4 {
/// unsafe {
/// vec2.push_bulk(4, |buf| {
/// input1.read_exact(buf)
/// }).unwrap();
/// }
/// }
///
/// // Check the result (vec2)
/// assert_eq!(&vec2, &bytes1[..])
/// ```
///
/// # Safety
///
/// The closure must fill whole slots because extended slots are not
/// initialized.
///