maybe_fut/api/io/
split.rs1use super::BufRead;
2
3#[derive(Debug)]
4pub struct Split<B> {
5 pub(crate) buf: B,
6 pub(crate) delim: u8,
7}
8
9impl<B: BufRead> Split<B> {
10 pub async fn next(&mut self) -> Option<std::io::Result<Vec<u8>>> {
12 let mut buf = Vec::new();
13 match self.buf.read_until(self.delim, &mut buf).await {
14 Ok(0) => None,
15 Ok(_n) => {
16 if buf[buf.len() - 1] == self.delim {
17 buf.pop();
18 }
19 Some(Ok(buf))
20 }
21 Err(e) => Some(Err(e)),
22 }
23 }
24}
25
26#[cfg(test)]
27mod test {
28
29 use super::*;
30 use crate::io::{BufReader, Read};
31
32 #[tokio::test]
33 async fn test_should_return_tokens() {
34 let data = b"line1|line2|line3";
35 let buf = BufReader::new(Buffer::new(data.to_vec()));
36 let mut tokens = Split { buf, delim: b'|' };
37
38 assert_eq!(tokens.next().await.unwrap().unwrap(), b"line1");
39 assert_eq!(tokens.next().await.unwrap().unwrap(), b"line2");
40 assert_eq!(tokens.next().await.unwrap().unwrap(), b"line3");
41 assert!(tokens.next().await.is_none());
42 }
43
44 struct Buffer {
45 data: Vec<u8>,
46 pos: usize,
47 }
48
49 impl Buffer {
50 fn new(data: Vec<u8>) -> Self {
51 Self { data, pos: 0 }
52 }
53 }
54
55 impl Read for Buffer {
56 async fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
57 if self.pos >= self.data.len() {
58 return Ok(0);
59 }
60 let n = std::cmp::min(buf.len(), self.data.len() - self.pos);
61 buf[..n].copy_from_slice(&self.data[self.pos..self.pos + n]);
62 self.pos += n;
63 Ok(n)
64 }
65 }
66}