moq_lite/ietf/
parameters.rs1use std::collections::{hash_map, HashMap};
2
3use num_enum::{FromPrimitive, IntoPrimitive};
4
5use crate::coding::*;
6
7const MAX_PARAMS: u64 = 64;
8
9#[derive(Debug, Copy, Clone, FromPrimitive, IntoPrimitive, Eq, Hash, PartialEq)]
10#[repr(u64)]
11pub enum ParameterVarInt {
12 MaxRequestId = 2,
13 MaxAuthTokenCacheSize = 4,
14 #[num_enum(catch_all)]
15 Unknown(u64),
16}
17
18#[derive(Debug, Copy, Clone, FromPrimitive, IntoPrimitive, Eq, Hash, PartialEq)]
19#[repr(u64)]
20pub enum ParameterBytes {
21 Path = 1,
22 AuthorizationToken = 3,
23 Authority = 5,
24 Implementation = 7,
25 #[num_enum(catch_all)]
26 Unknown(u64),
27}
28
29#[derive(Default, Debug, Clone)]
30pub struct Parameters {
31 vars: HashMap<ParameterVarInt, u64>,
32 bytes: HashMap<ParameterBytes, Vec<u8>>,
33}
34
35impl<V: Clone> Decode<V> for Parameters {
36 fn decode<R: bytes::Buf>(mut r: &mut R, version: V) -> Result<Self, DecodeError> {
37 let mut vars = HashMap::new();
38 let mut bytes = HashMap::new();
39
40 let count = u64::decode(r, version.clone())?;
42
43 if count > MAX_PARAMS {
44 return Err(DecodeError::TooMany);
45 }
46
47 for _ in 0..count {
48 let kind = u64::decode(r, version.clone())?;
49
50 if kind % 2 == 0 {
51 let kind = ParameterVarInt::from(kind);
52 match vars.entry(kind) {
53 hash_map::Entry::Occupied(_) => return Err(DecodeError::Duplicate),
54 hash_map::Entry::Vacant(entry) => entry.insert(u64::decode(&mut r, version.clone())?),
55 };
56 } else {
57 let kind = ParameterBytes::from(kind);
58 match bytes.entry(kind) {
59 hash_map::Entry::Occupied(_) => return Err(DecodeError::Duplicate),
60 hash_map::Entry::Vacant(entry) => entry.insert(Vec::<u8>::decode(&mut r, version.clone())?),
61 };
62 }
63 }
64
65 Ok(Parameters { vars, bytes })
66 }
67}
68
69impl<V: Clone> Encode<V> for Parameters {
70 fn encode<W: bytes::BufMut>(&self, w: &mut W, version: V) {
71 (self.vars.len() + self.bytes.len()).encode(w, version.clone());
72
73 for (kind, value) in self.vars.iter() {
74 u64::from(*kind).encode(w, version.clone());
75 value.encode(w, version.clone());
76 }
77
78 for (kind, value) in self.bytes.iter() {
79 u64::from(*kind).encode(w, version.clone());
80 value.encode(w, version.clone());
81 }
82 }
83}
84
85impl Parameters {
86 pub fn get_varint(&self, kind: ParameterVarInt) -> Option<u64> {
87 self.vars.get(&kind).copied()
88 }
89
90 pub fn set_varint(&mut self, kind: ParameterVarInt, value: u64) {
91 self.vars.insert(kind, value);
92 }
93
94 pub fn get_bytes(&self, kind: ParameterBytes) -> Option<&[u8]> {
95 self.bytes.get(&kind).map(|v| v.as_slice())
96 }
97
98 pub fn set_bytes(&mut self, kind: ParameterBytes, value: Vec<u8>) {
99 self.bytes.insert(kind, value);
100 }
101}