chiark / gitweb /
use queue
[hippotat.git] / src / queue.rs
1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: GPL-3.0-or-later
3 // There is NO WARRANTY.
4
5 use crate::prelude::*;
6
7 #[derive(Default,Clone)]
8 pub struct Queue {
9   content: usize,
10   eaten1: usize, // 0 <= eaten1 < queue.front()...len()
11   queue: VecDeque<Box<[u8]>>,
12 }
13
14 impl Queue {
15   pub fn push<B: Into<Box<[u8]>>>(&mut self, b: B) {
16     self.push_(b.into());
17   }
18   pub fn push_(&mut self, b: Box<[u8]>) {
19     let l = b.len();
20     self.queue.push_back(b);
21     self.content += l;
22   }
23   pub fn is_empty(&self) -> bool { self.content == 0 }
24 }
25
26 impl<B> Extend<B> for Queue where B: Into<Box<[u8]>> {
27   fn extend<I>(&mut self, it: I)
28   where I: IntoIterator<Item=B>
29   {
30     for b in it { self.push(b) }
31   }
32 }
33
34 impl hyper::body::Buf for Queue {
35   fn remaining(&self) -> usize { self.content }
36   fn chunk(&self) -> &[u8] {
37     let front = if let Some(f) = self.queue.front() { f } else { return &[] };
38     &front[ self.eaten1.. ]
39   }
40   fn advance(&mut self, cnt: usize) {
41     self.content -= cnt;
42     self.eaten1 += cnt;
43     loop {
44       if self.eaten1 == 0 { break }
45       let front = self.queue.front().unwrap();
46       if self.eaten1 < front.len() { break; }
47       self.eaten1 -= front.len();
48       self.queue.pop_front().unwrap();
49     }
50   }
51 }