1use crate::error::MyResult;
2use std::io::Read;
3
4pub fn read_until(
5 file: &mut dyn Read,
6 buffer: &mut Vec<u8>,
7 size: usize,
8) -> MyResult<usize> {
9 if let Some(size) = size.checked_sub(buffer.len()) {
10 if size > 0 {
11 file.take(size as u64).read_to_end(buffer)?;
12 }
13 }
14 Ok(buffer.len())
15}
16
17#[cfg(test)]
18mod tests {
19 use crate::error::MyResult;
20 use crate::util::file::read_until;
21 use pretty_assertions::assert_eq;
22 use std::io::Cursor;
23
24 #[test]
25 fn test_zero_bytes_are_not_read() -> MyResult<()> {
26 let (count, buffer) = read_until_multi(vec![0])?;
27 assert_eq!(count, 0);
28 assert_eq!(&buffer, b"");
29 Ok(())
30 }
31
32 #[test]
33 fn test_counted_bytes_are_partly_read() -> MyResult<()> {
34 let (count, buffer) = read_until_multi(vec![4])?;
35 assert_eq!(count, 4);
36 assert_eq!(&buffer, b"ABCD");
37 Ok(())
38 }
39
40 #[test]
41 fn test_counted_bytes_are_fully_read() -> MyResult<()> {
42 let (count, buffer) = read_until_multi(vec![12])?;
43 assert_eq!(count, 10);
44 assert_eq!(&buffer, b"ABCDEFGHIJ");
45 Ok(())
46 }
47
48 #[test]
49 fn test_counted_bytes_are_partly_and_partly_read() -> MyResult<()> {
50 let (count, buffer) = read_until_multi(vec![8, 4])?;
51 assert_eq!(count, 8);
52 assert_eq!(&buffer, b"ABCDEFGH");
53 Ok(())
54 }
55
56 #[test]
57 fn test_counted_bytes_are_partly_and_fully_read() -> MyResult<()> {
58 let (count, buffer) = read_until_multi(vec![4, 12])?;
59 assert_eq!(count, 10);
60 assert_eq!(&buffer, b"ABCDEFGHIJ");
61 Ok(())
62 }
63
64 fn read_until_multi(sizes: Vec<usize>) -> MyResult<(usize, Vec<u8>)> {
65 let mut file = Cursor::new(b"ABCDEFGHIJ".to_vec());
66 let mut buffer = Vec::new();
67 let mut count = 0;
68 for size in sizes {
69 count = read_until(&mut file, &mut buffer, size)?;
70 }
71 Ok((count, buffer))
72 }
73}