tsproto_packets/
lib.rs

1//! `tsproto-packets` parses and serializes TeamSpeak packets and commands.
2
3#[macro_use]
4extern crate rental;
5
6use std::fmt;
7
8use thiserror::Error;
9
10pub mod commands;
11pub mod packets;
12
13type Result<T> = std::result::Result<T, Error>;
14
15pub const S2C_HEADER_LEN: usize = 11;
16pub const C2S_HEADER_LEN: usize = 13;
17
18#[derive(Error, Debug)]
19#[non_exhaustive]
20pub enum Error {
21	#[error(transparent)]
22	Base64(#[from] base64::DecodeError),
23	#[error(transparent)]
24	Io(#[from] std::io::Error),
25	#[error(transparent)]
26	ParseInt(#[from] std::num::ParseIntError),
27	#[error(transparent)]
28	Utf8(#[from] std::str::Utf8Error),
29	#[error(transparent)]
30	StringUtf8(#[from] std::string::FromUtf8Error),
31
32	#[error("Invalid init step {0}")]
33	InvalidInitStep(u8),
34	#[error("Invalid audio codec {0}")]
35	InvalidCodec(u8),
36	#[error("Packet content is too short (length {0})")]
37	PacketContentTooShort(usize),
38	#[error("Packet is too short (length {0})")]
39	PacketTooShort(usize),
40	#[error("Cannot parse command ({0})")]
41	ParseCommand(String),
42	#[error("Got a packet with unknown type ({0})")]
43	UnknownPacketType(u8),
44	#[error("Tried to parse a packet from the wrong direction")]
45	WrongDirection,
46	#[error("Wrong mac, expected TS3INIT1 but got {0:?}")]
47	WrongInitMac(Vec<u8>),
48	#[error("Wrong packet type ({0:?})")]
49	WrongPacketType(packets::PacketType),
50}
51
52pub struct HexSlice<'a, T: fmt::LowerHex + 'a>(pub &'a [T]);
53
54impl<'a> fmt::Display for HexSlice<'a, u8> {
55	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56		write!(f, "Hex[")?;
57		if let Some((l, m)) = self.0.split_last() {
58			for b in m {
59				write!(f, "{:02x} ", b)?;
60			}
61			write!(f, "{:02x}", l)?;
62		}
63		write!(f, "]")
64	}
65}