tf_demo_parser/demo/data/
mod.rs1pub mod userinfo;
2
3use bitbuffer::{BitRead, BitReadStream, BitWrite, BitWriteStream, Endianness};
4use parse_display::Display;
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use std::cmp::Ordering;
7use std::fmt::{Debug, Display, Formatter};
8use std::ops::{Add, Sub};
9
10pub use userinfo::UserInfo;
11
12#[derive(Eq, PartialEq, Clone)]
13pub enum MaybeUtf8String {
14 Valid(String),
15 Invalid(Vec<u8>),
16}
17
18impl From<&'_ str> for MaybeUtf8String {
19 fn from(str: &'_ str) -> Self {
20 MaybeUtf8String::Valid(str.into())
21 }
22}
23
24impl Default for MaybeUtf8String {
25 fn default() -> Self {
26 MaybeUtf8String::Valid(String::new())
27 }
28}
29
30impl AsRef<str> for MaybeUtf8String {
31 fn as_ref(&self) -> &str {
32 match self {
33 MaybeUtf8String::Valid(s) => s.as_str(),
34 MaybeUtf8String::Invalid(_) => "-- Malformed utf8 --",
35 }
36 }
37}
38
39impl Debug for MaybeUtf8String {
40 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
41 match self {
42 MaybeUtf8String::Valid(s) => Debug::fmt(s, f),
43 MaybeUtf8String::Invalid(b) => f
44 .debug_struct("MaybeUtf8String::Invalid")
45 .field("data", b)
46 .finish(),
47 }
48 }
49}
50
51impl Display for MaybeUtf8String {
52 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
53 match self {
54 MaybeUtf8String::Valid(s) => Display::fmt(s, f),
55 MaybeUtf8String::Invalid(_) => write!(f, "-- Malformed utf8 --"),
56 }
57 }
58}
59
60impl MaybeUtf8String {
61 pub fn as_bytes(&self) -> &[u8] {
62 match self {
63 MaybeUtf8String::Valid(s) => s.as_bytes(),
64 MaybeUtf8String::Invalid(b) => b.as_ref(),
65 }
66 }
67}
68
69impl<'a, E: Endianness> BitRead<'a, E> for MaybeUtf8String {
70 fn read(stream: &mut BitReadStream<'a, E>) -> bitbuffer::Result<Self> {
71 match String::read(stream) {
72 Ok(str) => Ok(MaybeUtf8String::Valid(str)),
73 Err(bitbuffer::BitError::Utf8Error(_, size)) => {
74 stream.set_pos(stream.pos().saturating_sub(size * 8))?;
75 let mut data: Vec<u8> = stream.read_sized(size)?;
76 while data.last() == Some(&0) {
77 data.pop();
78 }
79 match String::from_utf8(data) {
80 Ok(str) => Ok(MaybeUtf8String::Valid(str)),
81 Err(e) => Ok(MaybeUtf8String::Invalid(e.into_bytes())),
82 }
83 }
84 Err(e) => Err(e),
85 }
86 }
87}
88
89impl<E: Endianness> BitWrite<E> for MaybeUtf8String {
90 fn write(&self, stream: &mut BitWriteStream<E>) -> bitbuffer::Result<()> {
91 stream.write_bytes(self.as_bytes())?;
92 stream.write(&0u8)
93 }
94}
95
96impl From<MaybeUtf8String> for String {
97 fn from(str: MaybeUtf8String) -> String {
98 match str {
99 MaybeUtf8String::Valid(s) => s,
100 MaybeUtf8String::Invalid(_) => "-- Malformed utf8 --".into(),
101 }
102 }
103}
104
105impl Serialize for MaybeUtf8String {
106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107 where
108 S: Serializer,
109 {
110 self.as_ref().serialize(serializer)
111 }
112}
113
114impl<'de> Deserialize<'de> for MaybeUtf8String {
115 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
116 where
117 D: Deserializer<'de>,
118 {
119 String::deserialize(deserializer).map(MaybeUtf8String::Valid)
120 }
121}
122
123#[cfg(feature = "schema")]
124impl schemars::JsonSchema for MaybeUtf8String {
125 fn schema_name() -> String {
126 String::schema_name()
127 }
128
129 fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
130 String::json_schema(gen)
131 }
132}
133
134#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
136#[derive(
137 Debug,
138 Clone,
139 Copy,
140 Ord,
141 PartialOrd,
142 Eq,
143 PartialEq,
144 BitRead,
145 BitWrite,
146 Serialize,
147 Deserialize,
148 Default,
149 Display,
150)]
151pub struct ServerTick(u32);
152
153impl ServerTick {
154 pub fn range_inclusive(&self, till: Self) -> impl Iterator<Item = Self> {
155 (self.0..=till.0).map(Self::from)
156 }
157}
158
159impl PartialEq<u32> for ServerTick {
160 fn eq(&self, other: &u32) -> bool {
161 *other == self.0
162 }
163}
164
165impl PartialOrd<u32> for ServerTick {
166 fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
167 self.0.partial_cmp(other)
168 }
169}
170
171impl PartialEq<ServerTick> for u32 {
172 fn eq(&self, other: &ServerTick) -> bool {
173 self.eq(&other.0)
174 }
175}
176
177impl PartialOrd<ServerTick> for u32 {
178 fn partial_cmp(&self, other: &ServerTick) -> Option<Ordering> {
179 self.partial_cmp(&other.0)
180 }
181}
182
183impl From<u32> for ServerTick {
184 fn from(tick: u32) -> Self {
185 ServerTick(tick)
186 }
187}
188
189impl From<ServerTick> for u32 {
190 fn from(tick: ServerTick) -> Self {
191 tick.0
192 }
193}
194
195impl Add<u32> for ServerTick {
196 type Output = ServerTick;
197
198 fn add(self, rhs: u32) -> Self::Output {
199 ServerTick(self.0 + rhs)
200 }
201}
202
203impl Add<ServerTick> for ServerTick {
204 type Output = ServerTick;
205
206 fn add(self, rhs: ServerTick) -> Self::Output {
207 ServerTick(self.0 + rhs.0)
208 }
209}
210
211impl Sub<u32> for ServerTick {
212 type Output = ServerTick;
213
214 fn sub(self, rhs: u32) -> Self::Output {
215 ServerTick(self.0 - rhs)
216 }
217}
218
219impl Sub<ServerTick> for ServerTick {
220 type Output = ServerTick;
221
222 fn sub(self, rhs: ServerTick) -> Self::Output {
223 ServerTick(self.0 - rhs.0)
224 }
225}
226
227#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
229#[derive(
230 Debug,
231 Clone,
232 Copy,
233 Ord,
234 PartialOrd,
235 Eq,
236 PartialEq,
237 BitRead,
238 BitWrite,
239 Serialize,
240 Deserialize,
241 Default,
242 Display,
243)]
244pub struct DemoTick(u32);
245
246impl DemoTick {
247 pub fn range_inclusive(&self, till: Self) -> impl Iterator<Item = Self> {
248 (self.0..=till.0).map(Self::from)
249 }
250}
251
252impl PartialEq<u32> for DemoTick {
253 fn eq(&self, other: &u32) -> bool {
254 *other == self.0
255 }
256}
257
258impl PartialOrd<u32> for DemoTick {
259 fn partial_cmp(&self, other: &u32) -> Option<Ordering> {
260 self.0.partial_cmp(other)
261 }
262}
263
264impl PartialEq<DemoTick> for u32 {
265 fn eq(&self, other: &DemoTick) -> bool {
266 self.eq(&other.0)
267 }
268}
269
270impl PartialOrd<DemoTick> for u32 {
271 fn partial_cmp(&self, other: &DemoTick) -> Option<Ordering> {
272 self.partial_cmp(&other.0)
273 }
274}
275
276impl From<u32> for DemoTick {
277 fn from(tick: u32) -> Self {
278 DemoTick(tick)
279 }
280}
281
282impl From<DemoTick> for u32 {
283 fn from(tick: DemoTick) -> Self {
284 tick.0
285 }
286}
287
288impl Add<u32> for DemoTick {
289 type Output = DemoTick;
290
291 fn add(self, rhs: u32) -> Self::Output {
292 DemoTick(self.0 + rhs)
293 }
294}
295
296impl Add<DemoTick> for DemoTick {
297 type Output = DemoTick;
298
299 fn add(self, rhs: DemoTick) -> Self::Output {
300 DemoTick(self.0 + rhs.0)
301 }
302}
303
304impl Sub<u32> for DemoTick {
305 type Output = DemoTick;
306
307 fn sub(self, rhs: u32) -> Self::Output {
308 DemoTick(self.0 - rhs)
309 }
310}
311
312impl Sub<DemoTick> for DemoTick {
313 type Output = DemoTick;
314
315 fn sub(self, rhs: DemoTick) -> Self::Output {
316 DemoTick(self.0 - rhs.0)
317 }
318}