1use std::net::{Ipv4Addr, Ipv6Addr};
4
5use bytes::{Buf, BufMut};
6use thiserror::Error;
7
8use crate::VarInt;
9
10#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
12#[error("unexpected end of buffer")]
13pub struct UnexpectedEnd;
14
15pub type Result<T> = ::std::result::Result<T, UnexpectedEnd>;
17
18pub trait Codec: Sized {
20 fn decode<B: Buf>(buf: &mut B) -> Result<Self>;
22 fn encode<B: BufMut>(&self, buf: &mut B);
24}
25
26impl Codec for u8 {
27 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
28 if buf.remaining() < 1 {
29 return Err(UnexpectedEnd);
30 }
31 Ok(buf.get_u8())
32 }
33 fn encode<B: BufMut>(&self, buf: &mut B) {
34 buf.put_u8(*self);
35 }
36}
37
38impl Codec for u16 {
39 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
40 if buf.remaining() < 2 {
41 return Err(UnexpectedEnd);
42 }
43 Ok(buf.get_u16())
44 }
45 fn encode<B: BufMut>(&self, buf: &mut B) {
46 buf.put_u16(*self);
47 }
48}
49
50impl Codec for u32 {
51 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
52 if buf.remaining() < 4 {
53 return Err(UnexpectedEnd);
54 }
55 Ok(buf.get_u32())
56 }
57 fn encode<B: BufMut>(&self, buf: &mut B) {
58 buf.put_u32(*self);
59 }
60}
61
62impl Codec for u64 {
63 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
64 if buf.remaining() < 8 {
65 return Err(UnexpectedEnd);
66 }
67 Ok(buf.get_u64())
68 }
69 fn encode<B: BufMut>(&self, buf: &mut B) {
70 buf.put_u64(*self);
71 }
72}
73
74impl Codec for Ipv4Addr {
75 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
76 if buf.remaining() < 4 {
77 return Err(UnexpectedEnd);
78 }
79 let mut octets = [0; 4];
80 buf.copy_to_slice(&mut octets);
81 Ok(octets.into())
82 }
83 fn encode<B: BufMut>(&self, buf: &mut B) {
84 buf.put_slice(&self.octets());
85 }
86}
87
88impl Codec for Ipv6Addr {
89 fn decode<B: Buf>(buf: &mut B) -> Result<Self> {
90 if buf.remaining() < 16 {
91 return Err(UnexpectedEnd);
92 }
93 let mut octets = [0; 16];
94 buf.copy_to_slice(&mut octets);
95 Ok(octets.into())
96 }
97 fn encode<B: BufMut>(&self, buf: &mut B) {
98 buf.put_slice(&self.octets());
99 }
100}
101
102pub(crate) trait BufExt {
103 fn get<T: Codec>(&mut self) -> Result<T>;
104 fn get_var(&mut self) -> Result<u64>;
105}
106
107impl<T: Buf> BufExt for T {
108 fn get<U: Codec>(&mut self) -> Result<U> {
109 U::decode(self)
110 }
111
112 fn get_var(&mut self) -> Result<u64> {
113 Ok(VarInt::decode(self)?.into_inner())
114 }
115}
116
117pub(crate) trait BufMutExt {
118 fn write<T: Codec>(&mut self, x: T);
119 fn write_var(&mut self, x: u64);
120}
121
122impl<T: BufMut> BufMutExt for T {
123 fn write<U: Codec>(&mut self, x: U) {
124 x.encode(self);
125 }
126
127 fn write_var(&mut self, x: u64) {
128 VarInt::from_u64(x).unwrap().encode(self);
129 }
130}