1use crate::varint::VarInt;
2use bytes::{Buf, BufMut};
3
4#[inline]
5#[allow(clippy::uninit_vec)]
6fn read_bytes_kvp(buf: &mut impl Buf, len: usize) -> Result<Vec<u8>, KvpError> {
7 if buf.remaining() < len {
8 return Err(KvpError::UnexpectedEnd);
9 }
10 let mut v = Vec::with_capacity(len);
11 unsafe {
13 v.set_len(len);
14 }
15 buf.copy_to_slice(&mut v);
16 Ok(v)
17}
18
19pub const MAX_KVP_VALUE_LEN: usize = 65535;
21
22#[derive(Debug, Clone, PartialEq, Eq)]
26pub enum KvpValue {
27 Varint(VarInt),
29 Bytes(Vec<u8>),
31}
32
33#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct KeyValuePair {
36 pub key: VarInt,
38 pub value: KvpValue,
40}
41
42#[derive(Debug, thiserror::Error, PartialEq, Eq, Clone)]
44pub enum KvpError {
45 #[error("odd key type requires length-prefixed value")]
47 MissingLength,
48 #[error("value length {0} exceeds maximum ({MAX_KVP_VALUE_LEN})")]
50 ValueTooLong(usize),
51 #[error("insufficient bytes")]
53 UnexpectedEnd,
54 #[error("varint error: {0}")]
56 VarInt(#[from] crate::varint::VarIntError),
57}
58
59impl KeyValuePair {
60 pub fn encode(&self, buf: &mut impl BufMut) {
62 self.key.encode(buf);
63 match &self.value {
64 KvpValue::Varint(v) => {
65 v.encode(buf);
67 }
68 KvpValue::Bytes(bytes) => {
69 VarInt::from_usize(bytes.len()).encode(buf);
71 buf.put_slice(bytes);
72 }
73 }
74 }
75
76 pub fn decode(buf: &mut impl Buf) -> Result<Self, KvpError> {
78 let key = VarInt::decode(buf)?;
79 let key_val = key.into_inner();
80
81 if key_val % 2 == 0 {
82 let value = VarInt::decode(buf)?;
84 Ok(KeyValuePair { key, value: KvpValue::Varint(value) })
85 } else {
86 let len = VarInt::decode(buf)?.into_inner() as usize;
88 if len > MAX_KVP_VALUE_LEN {
89 return Err(KvpError::ValueTooLong(len));
90 }
91 let bytes = read_bytes_kvp(buf, len)?;
92 Ok(KeyValuePair { key, value: KvpValue::Bytes(bytes) })
93 }
94 }
95
96 pub fn encode_list(pairs: &[KeyValuePair], buf: &mut impl BufMut) {
98 VarInt::from_usize(pairs.len()).encode(buf);
99 for pair in pairs {
100 pair.encode(buf);
101 }
102 }
103
104 pub fn decode_list(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, KvpError> {
106 let count = VarInt::decode(buf)?.into_inner() as usize;
107 let mut pairs = Vec::with_capacity(count);
108 for _ in 0..count {
109 pairs.push(KeyValuePair::decode(buf)?);
110 }
111 Ok(pairs)
112 }
113
114 pub fn decode_d07(buf: &mut impl Buf) -> Result<Self, KvpError> {
116 let key = VarInt::decode(buf)?;
117 let len = VarInt::decode(buf)?.into_inner() as usize;
118 if len > MAX_KVP_VALUE_LEN {
119 return Err(KvpError::ValueTooLong(len));
120 }
121 let bytes = read_bytes_kvp(buf, len)?;
122 Ok(KeyValuePair { key, value: KvpValue::Bytes(bytes) })
123 }
124
125 pub fn encode_d07(&self, buf: &mut impl BufMut) {
127 self.key.encode(buf);
128 match &self.value {
129 KvpValue::Varint(v) => {
130 VarInt::from_usize(v.encoded_len()).encode(buf);
131 v.encode(buf);
132 }
133 KvpValue::Bytes(bytes) => {
134 VarInt::from_usize(bytes.len()).encode(buf);
135 buf.put_slice(bytes);
136 }
137 }
138 }
139
140 pub fn decode_list_d07(buf: &mut impl Buf) -> Result<Vec<KeyValuePair>, KvpError> {
142 let count = VarInt::decode(buf)?.into_inner() as usize;
143 let mut pairs = Vec::with_capacity(count);
144 for _ in 0..count {
145 pairs.push(KeyValuePair::decode_d07(buf)?);
146 }
147 Ok(pairs)
148 }
149
150 pub fn encode_list_d07(pairs: &[KeyValuePair], buf: &mut impl BufMut) {
152 VarInt::from_usize(pairs.len()).encode(buf);
153 for pair in pairs {
154 pair.encode_d07(buf);
155 }
156 }
157}