tsproto_types/
lib.rs

1//! `tsproto-types` contains basic types and enums that are used within the TeamSpeak protocol.
2
3use std::borrow::{Borrow, Cow};
4use std::fmt;
5use std::u64;
6
7use bitflags::bitflags;
8use num_derive::{FromPrimitive, ToPrimitive};
9use ref_cast::RefCast;
10use serde::{Deserialize, Deserializer, Serialize};
11use time::OffsetDateTime;
12
13pub mod crypto;
14pub mod errors;
15pub mod versions;
16
17include!(concat!(env!("OUT_DIR"), "/enums.rs"));
18
19/// A `ClientId` identifies a client which is connected to a server.
20///
21/// Every client that we see on a server has a `ClientId`, even our own
22/// connection.
23#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
24pub struct ClientId(pub u16);
25/// Describes a client or server uid which is a base64
26/// encoded hash or a special reserved name.
27///
28/// This is saved raw, so the base64-decoded TeamSpeak uid.
29#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
30pub struct UidBuf(pub Vec<u8>);
31
32#[derive(Debug, Eq, PartialEq, RefCast, Serialize)]
33#[repr(transparent)]
34pub struct Uid(pub [u8]);
35
36impl ToOwned for Uid {
37	type Owned = UidBuf;
38	fn to_owned(&self) -> Self::Owned { UidBuf(self.0.to_owned()) }
39}
40impl Borrow<Uid> for UidBuf {
41	fn borrow(&self) -> &Uid { Uid::ref_cast(self.0.borrow()) }
42}
43impl AsRef<Uid> for UidBuf {
44	fn as_ref(&self) -> &Uid { self.borrow() }
45}
46impl core::ops::Deref for UidBuf {
47	type Target = Uid;
48	fn deref(&self) -> &Self::Target { self.borrow() }
49}
50impl<'a> From<&'a Uid> for Cow<'a, Uid> {
51	fn from(u: &'a Uid) -> Self { Cow::Borrowed(u) }
52}
53
54impl Uid {
55	pub fn from_bytes(data: &'_ [u8]) -> &Self { Uid::ref_cast(data) }
56
57	/// TeamSpeak uses a different encoding of the uid for fetching avatars.
58	///
59	/// The raw data (base64-decoded) is encoded in hex, but instead of using
60	/// [0-9a-f] with [a-p].
61	pub fn as_avatar(&self) -> String {
62		let mut res = String::with_capacity(self.0.len() * 2);
63		for b in &self.0 {
64			res.push((b'a' + (b >> 4)) as char);
65			res.push((b'a' + (b & 0xf)) as char);
66		}
67		res
68	}
69
70	pub fn is_server_admin(&self) -> bool { &self.0 == b"ServerAdmin" }
71}
72
73impl<'a, 'de: 'a> Deserialize<'de> for &'a Uid {
74	fn deserialize<D>(d: D) -> Result<&'a Uid, D::Error>
75	where D: Deserializer<'de> {
76		let data = <&[u8]>::deserialize(d)?;
77		Ok(Uid::from_bytes(data))
78	}
79}
80
81/// The database id of a client.
82///
83/// This is the id which is saved for a client in the database of one specific
84/// server.
85#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
86pub struct ClientDbId(pub u64);
87
88/// Identifies a channel on a server.
89#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
90pub struct ChannelId(pub u64);
91
92/// Identifies a server group on a server.
93#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
94pub struct ServerGroupId(pub u64);
95
96/// Identifies a channel group on a server.
97#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
98pub struct ChannelGroupId(pub u64);
99
100#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
101pub struct IconId(pub u32);
102
103#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
104pub struct Permission(pub u32);
105impl Permission {
106	/// Never fails
107	pub fn from_u32(i: u32) -> Option<Self> { Some(Permission(i)) }
108	/// Never fails
109	pub fn to_u32(self) -> Option<u32> { Some(self.0) }
110}
111
112#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
113pub enum ClientType {
114	Normal,
115	/// Server query client
116	Query {
117		admin: bool,
118	},
119}
120
121#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
122pub enum MaxClients {
123	Unlimited,
124	Inherited,
125	Limited(u16),
126}
127
128#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
129pub struct TalkPowerRequest {
130	pub time: OffsetDateTime,
131	pub message: String,
132}
133
134#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
135pub struct Invoker {
136	pub name: String,
137	pub id: ClientId,
138	pub uid: Option<UidBuf>,
139}
140
141#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
142pub struct InvokerRef<'a> {
143	pub name: &'a str,
144	pub id: ClientId,
145	pub uid: Option<&'a Uid>,
146}
147
148impl Invoker {
149	pub fn as_ref(&self) -> InvokerRef {
150		InvokerRef { name: &self.name, id: self.id, uid: self.uid.as_ref().map(|u| u.as_ref()) }
151	}
152}
153
154impl fmt::Display for ClientId {
155	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
156}
157impl fmt::Display for Uid {
158	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159		write!(f, "{}", base64::encode(&self.0))
160	}
161}
162impl fmt::Display for ClientDbId {
163	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
164}
165impl fmt::Display for ChannelId {
166	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
167}
168impl fmt::Display for ServerGroupId {
169	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
170}
171impl fmt::Display for ChannelGroupId {
172	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
173}