quinn_proto/
coding.rs

1//! Coding related traits.
2
3use std::net::{Ipv4Addr, Ipv6Addr};
4
5use bytes::{Buf, BufMut};
6use thiserror::Error;
7
8use crate::VarInt;
9
10/// Error indicating that the provided buffer was too small
11#[derive(Error, Debug, Copy, Clone, Eq, PartialEq)]
12#[error("unexpected end of buffer")]
13pub struct UnexpectedEnd;
14
15/// Coding result type
16pub type Result<T> = ::std::result::Result<T, UnexpectedEnd>;
17
18/// Infallible encoding and decoding of QUIC primitives
19pub trait Codec: Sized {
20    /// Decode a `Self` from the provided buffer, if the buffer is large enough
21    fn decode<B: Buf>(buf: &mut B) -> Result<Self>;
22    /// Append the encoding of `self` to the provided buffer
23    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}