1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 18:24:05 +02:00

tryFromPrimitive

This commit is contained in:
Robin Appelman 2019-12-19 18:48:50 +01:00
commit ee63f2ab93
11 changed files with 53 additions and 39 deletions

View file

@ -11,5 +11,5 @@ matrix:
install: install:
- ls ~/.cargo/bin/rustig || cargo install --git https://github.com/Technolution/rustig rustig - ls ~/.cargo/bin/rustig || cargo install --git https://github.com/Technolution/rustig rustig
script: script:
- cargo build - cargo build --features no-panic
- cargo test - cargo test

12
Cargo.lock generated
View file

@ -258,6 +258,16 @@ name = "memchr"
version = "2.2.1" version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "no-panic"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.10" version = "0.2.10"
@ -568,6 +578,7 @@ dependencies = [
"err-derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "err-derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"no-panic 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"num_enum 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_enum 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parse-display 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parse-display 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -662,6 +673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" "checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
"checksum main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3516df0fb44d98fe6d6e859d224adfb7b6686447937e5b96308d6061595eed04" "checksum main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3516df0fb44d98fe6d6e859d224adfb7b6686447937e5b96308d6061595eed04"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum no-panic 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a11c6db47b62f887ae15a0d02c5b24eb9a815536812bc46ca45305a6d22e5675"
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum num_enum 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be601e38e20a6f3d01049d85801cb9b7a34a8da7a0da70df507bbde7735058c8" "checksum num_enum 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be601e38e20a6f3d01049d85801cb9b7a34a8da7a0da70df507bbde7735058c8"
"checksum num_enum_derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b59f30f6a043f2606adbd0addbf1eef6f2e28e8c4968918b63b7ff97ac0db2a7" "checksum num_enum_derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b59f30f6a043f2606adbd0addbf1eef6f2e28e8c4968918b63b7ff97ac0db2a7"

View file

@ -26,6 +26,7 @@ parse-display = "0.1"
main_error = "0.1.0" main_error = "0.1.0"
jemallocator = { version = "0.3", optional = true } jemallocator = { version = "0.3", optional = true }
better-panic = { version = "0.1", optional = true } better-panic = { version = "0.1", optional = true }
no-panic = { version = "0.1", optional = true }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "0.6" pretty_assertions = "0.6"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"players":[{"entity":2,"position":{"x":5209.61,"y":-1013.047,"z":296.03125},"health":125,"max_health":125,"class":1,"team":"blue","view_angle":64.04692,"state":"Alive"},{"entity":3,"position":{"x":4563.5,"y":-1381.375,"z":369.125},"health":135,"max_health":200,"class":3,"team":"red","view_angle":28.504398,"state":"Alive"},{"entity":4,"position":{"x":4334.875,"y":-1428.875,"z":296.0},"health":104,"max_health":150,"class":5,"team":"red","view_angle":355.0733,"state":"Death"},{"entity":5,"position":{"x":5207.0,"y":-1077.0,"z":296.0},"health":175,"max_health":175,"class":4,"team":"blue","view_angle":33.079178,"state":"Alive"},{"entity":6,"position":{"x":5046.0,"y":-1077.0,"z":296.0},"health":125,"max_health":125,"class":1,"team":"blue","view_angle":180.17595,"state":"Alive"},{"entity":7,"position":{"x":5046.0,"y":-1013.0,"z":296.0},"health":150,"max_health":150,"class":5,"team":"blue","view_angle":180.17595,"state":"Alive"},{"entity":8,"position":{"x":4124.375,"y":-990.375,"z":162.0},"health":260,"max_health":175,"class":4,"team":"red","view_angle":355.42523,"state":"Alive"},{"entity":10,"position":{"x":5046.0,"y":-953.25,"z":296.0},"health":200,"max_health":200,"class":3,"team":"blue","view_angle":180.17595,"state":"Alive"},{"entity":12,"position":{"x":3954.25,"y":-1329.875,"z":232.0},"health":132,"max_health":125,"class":2,"team":"red","view_angle":17.947214,"state":"Alive"},{"entity":13,"position":{"x":4563.5,"y":-1381.375,"z":369.125},"health":1,"max_health":200,"class":3,"team":"red","view_angle":9.853373,"state":"Death"},{"entity":11,"position":{"x":5046.0,"y":-1141.0,"z":296.0},"health":175,"max_health":175,"class":7,"team":"Other","view_angle":180.17595,"state":"Alive"},{"entity":9,"position":{"x":3707.125,"y":-444.375,"z":342.5},"health":125,"max_health":125,"class":1,"team":"Other","view_angle":110.14663,"state":"Alive"}],"buildings":[]} {"players":[{"entity":2,"position":{"x":5209.61,"y":-1013.047,"z":296.03125},"health":125,"max_health":125,"class":1,"team":"blue","view_angle":64.04692,"state":"Alive"},{"entity":3,"position":{"x":4563.5,"y":-1381.375,"z":369.125},"health":135,"max_health":200,"class":3,"team":"red","view_angle":28.504398,"state":"Alive"},{"entity":4,"position":{"x":4334.875,"y":-1428.875,"z":296.0},"health":104,"max_health":150,"class":5,"team":"red","view_angle":355.0733,"state":"Death"},{"entity":5,"position":{"x":5207.0,"y":-1077.0,"z":296.0},"health":175,"max_health":175,"class":4,"team":"blue","view_angle":33.079178,"state":"Alive"},{"entity":6,"position":{"x":5046.0,"y":-1077.0,"z":296.0},"health":125,"max_health":125,"class":1,"team":"blue","view_angle":180.17595,"state":"Alive"},{"entity":7,"position":{"x":5046.0,"y":-1013.0,"z":296.0},"health":150,"max_health":150,"class":5,"team":"blue","view_angle":180.17595,"state":"Alive"},{"entity":8,"position":{"x":4124.375,"y":-990.375,"z":162.0},"health":260,"max_health":175,"class":4,"team":"red","view_angle":355.42523,"state":"Alive"},{"entity":10,"position":{"x":5046.0,"y":-953.25,"z":296.0},"health":200,"max_health":200,"class":3,"team":"blue","view_angle":180.17595,"state":"Alive"},{"entity":12,"position":{"x":3954.25,"y":-1329.875,"z":232.0},"health":132,"max_health":125,"class":2,"team":"red","view_angle":17.947214,"state":"Alive"},{"entity":13,"position":{"x":4563.5,"y":-1381.375,"z":369.125},"health":1,"max_health":200,"class":3,"team":"red","view_angle":9.853373,"state":"Death"},{"entity":11,"position":{"x":5046.0,"y":-1141.0,"z":296.0},"health":175,"max_health":175,"class":7,"team":"other","view_angle":180.17595,"state":"Alive"},{"entity":9,"position":{"x":3707.125,"y":-444.375,"z":342.5},"health":125,"max_health":125,"class":1,"team":"other","view_angle":110.14663,"state":"Alive"}],"buildings":[]}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"chat":[],"users":{"2":{"classes":{},"name":"Icewind | demos.tf","userId":2,"steamId":"[U:1:64229260]","team":"Other"}},"deaths":[],"rounds":[],"startTick":4854,"intervalPerTick":0.015} {"chat":[],"users":{"2":{"classes":{},"name":"Icewind | demos.tf","userId":2,"steamId":"[U:1:64229260]","team":"other"}},"deaths":[],"rounds":[],"startTick":4854,"intervalPerTick":0.015}

View file

@ -13,6 +13,8 @@ use crate::demo::packet::stringtable::StringTableEntry;
use crate::demo::parser::handler::MessageHandler; use crate::demo::parser::handler::MessageHandler;
use crate::demo::vector::Vector; use crate::demo::vector::Vector;
use crate::{ParserState, ReadResult, Stream}; use crate::{ParserState, ReadResult, Stream};
use num_enum::TryFromPrimitive;
use std::convert::TryFrom;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
@ -34,28 +36,28 @@ impl ChatMassage {
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
#[serde(rename_all = "lowercase")]
#[repr(u8)]
pub enum Team { pub enum Team {
Other = 0, Other = 0,
Spectator = 1, Spectator = 1,
#[serde(rename = "red")]
Red = 2, Red = 2,
#[serde(rename = "blue")]
Blue = 3, Blue = 3,
} }
impl Team { impl Team {
pub fn new(number: u16) -> Self { pub fn new<U>(number: U) -> Self
match number { where
1 => Team::Spectator, u8: TryFrom<U>,
2 => Team::Red, {
3 => Team::Blue, Team::try_from(u8::try_from(number).unwrap_or_default()).unwrap_or(Team::Other)
_ => Team::Other,
}
} }
} }
#[derive(Debug, Clone, Serialize_repr, Deserialize_repr, Copy, PartialEq, Eq, Hash)] #[derive(
Debug, Clone, Serialize_repr, Deserialize_repr, Copy, PartialEq, Eq, Hash, TryFromPrimitive,
)]
#[repr(u8)] #[repr(u8)]
pub enum Class { pub enum Class {
Other = 0, Other = 0,
@ -71,19 +73,11 @@ pub enum Class {
} }
impl Class { impl Class {
pub fn new(number: u16) -> Self { pub fn new<U>(number: U) -> Self
match number { where
1 => Class::Scout, u8: TryFrom<U>,
2 => Class::Sniper, {
3 => Class::Solder, Class::try_from(u8::try_from(number).unwrap_or_default()).unwrap_or(Class::Other)
4 => Class::Demoman,
5 => Class::Medic,
6 => Class::Heavy,
7 => Class::Pyro,
8 => Class::Spy,
9 => Class::Engineer,
_ => Class::Other,
}
} }
} }
@ -94,12 +88,14 @@ pub struct ClassList([u8; 10]);
impl Index<Class> for ClassList { impl Index<Class> for ClassList {
type Output = u8; type Output = u8;
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
fn index(&self, class: Class) -> &Self::Output { fn index(&self, class: Class) -> &Self::Output {
&self.0[class as u8 as usize] &self.0[class as u8 as usize]
} }
} }
impl IndexMut<Class> for ClassList { impl IndexMut<Class> for ClassList {
#[cfg_attr(feature = "no-panic", no_panic::no_panic)]
fn index_mut(&mut self, class: Class) -> &mut Self::Output { fn index_mut(&mut self, class: Class) -> &mut Self::Output {
&mut self.0[class as u8 as usize] &mut self.0[class as u8 as usize]
} }
@ -143,6 +139,12 @@ impl From<u32> for UserId {
} }
} }
impl From<u16> for UserId {
fn from(int: u16) -> Self {
UserId((int & 255) as u8)
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Spawn { pub struct Spawn {
pub user: UserId, pub user: UserId,
@ -154,7 +156,7 @@ pub struct Spawn {
impl Spawn { impl Spawn {
pub fn from_event(event: &PlayerSpawnEvent, tick: u32) -> Self { pub fn from_event(event: &PlayerSpawnEvent, tick: u32) -> Self {
Spawn { Spawn {
user: UserId((event.user_id & 255) as u8), user: UserId::from(event.user_id),
class: Class::new(event.class), class: Class::new(event.class),
team: Team::new(event.team), team: Team::new(event.team),
tick, tick,
@ -196,16 +198,16 @@ pub struct Death {
impl Death { impl Death {
pub fn from_event(event: &PlayerDeathEvent, tick: u32) -> Self { pub fn from_event(event: &PlayerDeathEvent, tick: u32) -> Self {
let assister = if event.assister < (16 * 1024) { let assister = if event.assister < (16 * 1024) {
Some(UserId((event.assister & 255) as u8)) Some(UserId::from(event.assister))
} else { } else {
None None
}; };
Death { Death {
assister, assister,
tick, tick,
killer: UserId((event.attacker & 255) as u8), killer: UserId::from(event.attacker),
weapon: event.weapon.clone(), weapon: event.weapon.clone(),
victim: UserId((event.user_id & 255) as u8), victim: UserId::from(event.user_id),
} }
} }
} }
@ -220,7 +222,7 @@ pub struct Round {
impl Round { impl Round {
pub fn from_event(event: &TeamPlayRoundWinEvent, tick: u32) -> Self { pub fn from_event(event: &TeamPlayRoundWinEvent, tick: u32) -> Self {
Round { Round {
winner: Team::new(event.team as u16), winner: Team::new(event.team),
length: event.round_time, length: event.round_time,
end_tick: tick, end_tick: tick,
} }

View file

@ -201,8 +201,7 @@ impl GameStateAnalyser {
{ {
match prop.definition.owner_table.as_str() { match prop.definition.owner_table.as_str() {
"m_iTeam" => { "m_iTeam" => {
player.team = player.team = Team::new(i64::try_from(&prop.value).unwrap_or_default())
Team::new(i64::try_from(&prop.value).unwrap_or_default() as u16)
} }
"m_iMaxHealth" => { "m_iMaxHealth" => {
player.max_health = player.max_health =
@ -210,7 +209,7 @@ impl GameStateAnalyser {
} }
"m_iPlayerClass" => { "m_iPlayerClass" => {
player.class = player.class =
Class::new(i64::try_from(&prop.value).unwrap_or_default() as u16) Class::new(i64::try_from(&prop.value).unwrap_or_default())
} }
_ => {} _ => {}
} }