pub const TAG_HANDSHAKE_1: u8 = 1;
pub const TAG_HANDSHAKE_2: u8 = 2;
pub const TAG_TRANSPORT: u8 = 3;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum InnerKind {
Handshake1,
Handshake2,
Transport,
}
impl InnerKind {
pub fn tag(self) -> u8 {
match self {
Self::Handshake1 => TAG_HANDSHAKE_1,
Self::Handshake2 => TAG_HANDSHAKE_2,
Self::Transport => TAG_TRANSPORT,
}
}
}
pub fn encode_inner(kind: InnerKind, body: &[u8]) -> Vec<u8> {
let mut out = Vec::with_capacity(1 + body.len());
out.push(kind.tag());
out.extend_from_slice(body);
out
}
pub fn decode_inner(bytes: &[u8]) -> Option<(InnerKind, &[u8])> {
let (&tag, body) = bytes.split_first()?;
let kind = match tag {
TAG_HANDSHAKE_1 => InnerKind::Handshake1,
TAG_HANDSHAKE_2 => InnerKind::Handshake2,
TAG_TRANSPORT => InnerKind::Transport,
_ => return None,
};
Some((kind, body))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn roundtrip_and_unknown_tag() {
let b = encode_inner(InnerKind::Transport, b"x");
assert_eq!(decode_inner(&b), Some((InnerKind::Transport, &b"x"[..])));
assert_eq!(decode_inner(&[9, 1]), None);
assert_eq!(decode_inner(&[]), None);
}
}