nix_compat/nar/reader/async/
read.rs1use tokio::io::{
2 self, AsyncReadExt,
3 ErrorKind::{InvalidData, UnexpectedEof},
4};
5
6use crate::nar::wire::Tag;
7
8use super::Reader;
9
10pub async fn token<const N: usize>(reader: &mut Reader<'_>, token: &[u8; N]) -> io::Result<()> {
12 let mut buf = [0u8; N];
13
14 let mut token = &token[..];
18 let mut buf = &mut buf[..];
19
20 while !token.is_empty() {
21 match reader.read(buf).await? {
22 0 => {
23 return Err(UnexpectedEof.into());
24 }
25 n => {
26 let (t, b);
27 (t, token) = token.split_at(n);
28 (b, buf) = buf.split_at_mut(n);
29
30 if t != b {
31 return Err(InvalidData.into());
32 }
33 }
34 }
35 }
36
37 Ok(())
38}
39
40pub async fn tag<T: Tag>(reader: &mut Reader<'_>) -> io::Result<T> {
42 let mut buf = T::make_buf();
43 let buf = buf.as_mut();
44
45 reader.read_exact(&mut buf[..T::MIN]).await?;
47
48 let tag = T::from_u8(buf[T::OFF]).ok_or(InvalidData)?;
50 let (head, tail) = tag.as_bytes().split_at(T::MIN);
51
52 if buf[..T::MIN] != *head {
54 return Err(InvalidData.into());
55 }
56
57 if !tail.is_empty() {
59 let rest = tail.len();
60 reader.read_exact(&mut buf[..rest]).await?;
61
62 if buf[..rest] != *tail {
64 return Err(InvalidData.into());
65 }
66 }
67
68 Ok(tag)
69}