1use crate::{address::AddressError, Address, Error, ProtocolError};
2use bytes::{BufMut, BytesMut};
3use std::io::Error as IoError;
4use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
5
6#[derive(Clone, Debug)]
16pub struct UdpHeader {
17 pub frag: u8,
18 pub address: Address,
19}
20
21impl UdpHeader {
22 pub const fn new(frag: u8, address: Address) -> Self {
23 Self { frag, address }
24 }
25
26 pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>
27 where
28 R: AsyncRead + Unpin,
29 {
30 r.read_exact(&mut [0; 2]).await?;
31
32 let frag = r.read_u8().await?;
33
34 let addr = Address::read_from(r).await.map_err(|err| match err {
35 AddressError::Io(err) => Error::Io(err),
36 AddressError::InvalidType(code) => {
37 Error::Protocol(ProtocolError::InvalidAddressTypeInUdpHeader {
38 frag,
39 address_type: code,
40 })
41 }
42 })?;
43
44 Ok(Self::new(frag, addr))
45 }
46
47 pub async fn write_to<W>(&self, w: &mut W) -> Result<(), IoError>
48 where
49 W: AsyncWrite + Unpin,
50 {
51 let mut buf = BytesMut::with_capacity(self.serialized_len());
52 self.write_to_buf(&mut buf);
53 w.write_all(&buf).await?;
54
55 Ok(())
56 }
57
58 pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {
59 buf.put_bytes(0x00, 2);
60 buf.put_u8(self.frag);
61 self.address.write_to_buf(buf);
62 }
63
64 pub fn serialized_len(&self) -> usize {
65 2 + 1 + self.address.serialized_len()
66 }
67}