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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/// Fill a collection from an iterator until its capacity has been reached.
///
/// # Examples
///
/// An option's capacity has been reached when it contains an item in a `Some`. It consumes no
/// items from the iterator when it already contains one and consumes exactly one if it is
/// currently `None`.
///
/// ```
/// # use fill::Fill;
/// let mut option = None;
///
/// let spilled = option.fill_and_keep_tail(42..);
/// assert_eq!(option, Some(42));
/// assert_eq!(spilled.start, 43);
/// ```
pub trait Fill<T> {
    /// Fill empty space with contents from an iterator.
    ///
    /// The iterator should be dropped and not exhausted when no more items can be pushed into the
    /// container.
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=T>;

    /// Fill the container from an iterator, returning it afterwards.
    ///
    /// This is only a shorthand for iterating by reference when the caller wants to inspect the
    /// state after filling or when a fall-back is supposed to consume remaining elements.
    fn fill_and_keep_tail<I>(&mut self, iter: I) -> I::IntoIter
        where I: IntoIterator<Item=T>
    {
        let mut iter = iter.into_iter();
        self.fill(&mut iter);
        iter
    }

    /// Fill the container and count the number of pulled items.
    ///
    /// The count is equal to the number of elements that have been pulled from the iterator. On
    /// well-behaved containers this shall equal the number of items inserted as it should do so
    /// for all items.
    ///
    /// ## Examples
    ///
    /// For containers with a statically known capacity this can be an alternative to checking the
    /// current state after a fill operation.
    ///
    /// ```
    /// # use fill::Fill;
    /// let mut option = None;
    /// assert_eq!(option.fill_count(0..), 1);
    /// assert_eq!(option.fill_count(1..), 0);
    /// ```
    fn fill_count<I>(&mut self, iter: I) -> usize
        where I: IntoIterator<Item=T>
    {
        let mut count = 0;
        self.fill(iter.into_iter().inspect(|_| count += 1));
        count
    }

    /// Fill the container and return if more elements could have been available.
    ///
    /// This returns `None` if the iterator was exhausted before the container could be filled
    /// completely. Otherwise it will return `Some(_)` containing the remaining iterator.
    ///
    /// Note that a well behaved fillable container should not poll more items when it is full so
    /// that this method should return `Some` but when it violates this assumption then the method
    /// might return `None` instead as the implementation merely detects if the fused iterator was
    /// exhausted.
    ///
    /// ## Examples
    ///
    /// ```
    /// # use fill::Fill;
    /// let mut option = None;
    /// assert_eq!(option.checked_fill(None).is_some(), false);
    /// assert_eq!(option.checked_fill(0..).is_some(), true);
    /// ```
    ///
    /// Note that a full container will not poll the iterator, so even an 'obviously empty'
    /// iterator will cause the function to return true.
    ///
    /// ```
    /// # use fill::Fill;
    /// let mut full = Some(0);
    /// assert_eq!(full.checked_fill(None).is_some(), true);
    /// ```
    fn checked_fill<I>(&mut self, iter: I) -> Option<I::IntoIter>
        where I: IntoIterator<Item=T>
    {
        struct Overflow<I> {
            overflow: bool,
            inner: I,
        }

        impl<I: Iterator> Iterator for Overflow<I> {
            type Item = I::Item;
            fn next(&mut self) -> Option<I::Item> {
                let next = self.inner.next();
                self.overflow &= next.is_some();
                next
            }
        }

        let mut iter = iter.into_iter();
        // We iterate by reference over the fused iterator instead of iterating directly. This
        // avoids exhausting the iterator in some unexpected way when we return `None`.
        let overflow = self.fill_and_keep_tail(Overflow {
            overflow: true,
            inner: iter.by_ref().fuse(),
        }).overflow;
        Some(iter).filter(|_| overflow)
    }
}

#[cfg(feature = "alloc")]
/// Fills the vector as far as possible without reallocating.
impl<T> Fill<T> for alloc::vec::Vec<T> {
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=T>
    {
        for item in iter.into_iter().take(self.capacity() - self.len()) {
            self.push(item);
        }
    }
}

#[cfg(feature = "alloc")]
/// Fills the queue as far as possible without reallocating.
impl<T> Fill<T> for alloc::collections::VecDeque<T> {
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=T>
    {
        for item in iter.into_iter().take(self.capacity() - self.len()) {
            self.push_back(item);
        }
    }
}

/// Consumes all items until the first `None`.
impl Fill<()> for () {
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=()>
    {
        for () in iter { }
    }
}

/// If the option does not yet contain an item, insert the next item of the iterator.
///
/// Note that this will call `iter.next()` at most once. The option will still be empty if the
/// iterator is not fused and returns `None` as the first result of that call.
impl<T> Fill<T> for Option<T> {
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=T>
    {
        let mut iter = iter.into_iter();
        match self {
            None => *self = iter.next(),
            Some(_) => (),
        }
    }
}

/// Tries to fill the container in the `Ok`.
///
/// A result is full if it contains an error, or if the container in `Ok` is full.
impl<C, E, T> Fill<Result<T, E>> for Result<C, E>
    where C: Fill<T>,
{
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=Result<T, E>>
    {
        let mut iter = iter.into_iter();

        let container = match self {
            Ok(container) => container,
            Err(_) => return,
        };

        let err = loop {
            match iter.next() {
                None => return,
                Some(Err(err)) => break err,
                Some(Ok(ok)) => {
                    container.fill(core::iter::once(ok));
                },
            };
        };

        *self = Err(err);
    }
}

/// Advances self while inserting elements from the iterator.
impl<T> Fill<T> for core::slice::IterMut<'_, T> {
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=T>
    {
        let mut iter = iter.into_iter();
        // Do not use `zip` to control the exact calls to `next`.
        while self.len() != 0 {
            if let Some(item) = iter.next() {
                *self.next().unwrap() = item;
            } else {
                break
            }
        }
    }
}

/// Advances self while swapping elements with the iterator.
impl<'a, T: 'a> Fill<&'a mut T> for core::slice::IterMut<'_, T> {
    fn fill<I>(&mut self, iter: I)
        where I: IntoIterator<Item=&'a mut T>
    {
        let mut iter = iter.into_iter();
        // Do not use `zip` to control the exact calls to `next`.
        while self.len() != 0 {
            if let Some(item) = iter.next() {
                core::mem::swap(self.next().unwrap(), item);
            } else {
                break
            }
        }
    }
}