From 8b41ad5108b8ff72fe80ae3c92a27c0019bbd9de Mon Sep 17 00:00:00 2001 From: Lol3rrr Date: Sun, 22 Sep 2024 22:25:15 +0200 Subject: [PATCH] Fix (clippy) warnings --- src/bitreader.rs | 26 +++++------ src/container.rs | 6 ++- src/frame.rs | 39 ++++++++++------ src/lib.rs | 2 +- src/parser.rs | 30 +++++------- src/parser/decoder.rs | 12 ++--- src/parser/decoder/quantizedfloat.rs | 20 +++----- src/parser/fieldpath.rs | 6 +++ src/parser/propcontroller.rs | 68 ++++++++++------------------ src/parser/sendtables.rs | 18 ++++---- src/values.rs | 6 +-- tests/parse.rs | 30 +++++------- 12 files changed, 122 insertions(+), 141 deletions(-) diff --git a/src/bitreader.rs b/src/bitreader.rs index f4be38b..0e24d3f 100644 --- a/src/bitreader.rs +++ b/src/bitreader.rs @@ -45,7 +45,7 @@ impl<'a> Bitreader<'a> { } #[inline(always)] pub fn bits_remaining(&mut self) -> Option { - Some(self.reader.bits_remaining()?) + self.reader.bits_remaining() } #[inline(always)] pub fn read_nbits(&mut self, n: u32) -> Result { @@ -54,16 +54,16 @@ impl<'a> Bitreader<'a> { } let b = self.peek(n); self.consume(n); - return Ok(b as u32); + Ok(b as u32) } #[inline(always)] pub fn read_u_bit_var(&mut self) -> Result { let bits = self.read_nbits(6)?; match bits & 0b110000 { - 0b10000 => return Ok((bits & 0b1111) | (self.read_nbits(4)? << 4)), - 0b100000 => return Ok((bits & 0b1111) | (self.read_nbits(8)? << 4)), - 0b110000 => return Ok((bits & 0b1111) | (self.read_nbits(28)? << 4)), - _ => return Ok(bits), + 0b10000 => Ok((bits & 0b1111) | (self.read_nbits(4)? << 4)), + 0b100000 => Ok((bits & 0b1111) | (self.read_nbits(8)? << 4)), + 0b110000 => Ok((bits & 0b1111) | (self.read_nbits(28)? << 4)), + _ => Ok(bits), } } #[inline(always)] @@ -73,7 +73,7 @@ impl<'a> Bitreader<'a> { if x & 1 != 0 { y = !y; } - Ok(y as i32) + Ok(y) } #[inline(always)] pub fn read_varint(&mut self) -> Result { @@ -160,18 +160,18 @@ impl<'a> Bitreader<'a> { } pub fn read_ubit_var_fp(&mut self) -> Result { if self.read_boolean()? { - return Ok(self.read_nbits(2)?); + return self.read_nbits(2); } if self.read_boolean()? { - return Ok(self.read_nbits(4)?); + return self.read_nbits(4); } if self.read_boolean()? { - return Ok(self.read_nbits(10)?); + return self.read_nbits(10); } if self.read_boolean()? { - return Ok(self.read_nbits(17)?); + return self.read_nbits(17); } - return Ok(self.read_nbits(31)?); + self.read_nbits(31) } #[inline(always)] pub fn read_bit_coord(&mut self) -> Result { @@ -190,7 +190,7 @@ impl<'a> Bitreader<'a> { frac_val = self.read_nbits(5)?; } let resol: f64 = 1.0 / (1 << 5) as f64; - let result: f32 = (int_val as f64 + (frac_val as f64 * resol) as f64) as f32; + let result: f32 = (int_val as f64 + (frac_val as f64 * resol)) as f32; if sign { Ok(-result) } else { diff --git a/src/container.rs b/src/container.rs index fa5f5ee..5958a53 100644 --- a/src/container.rs +++ b/src/container.rs @@ -9,6 +9,9 @@ pub enum ParseContainerError { Other(&'static str), } +/// A Container models the outer layer of a CS2 demo, which starts with a specific magic string and +/// some other values. Then it just stores the raw bytes afterwards, that contain the actual demo +/// data #[derive(Debug)] pub struct Container<'b> { pub magic: &'b str, @@ -16,6 +19,7 @@ pub struct Container<'b> { } impl<'b> Container<'b> { + /// Attempts to parse the given bytes into a valid cs2 demo container pub fn parse<'ib>(input: &'ib [u8]) -> Result where 'ib: 'b, @@ -25,7 +29,7 @@ impl<'b> Container<'b> { } let magic = - core::str::from_utf8(&input[..8]).map_err(|e| ParseContainerError::InvalidMagic(e))?; + core::str::from_utf8(&input[..8]).map_err(ParseContainerError::InvalidMagic)?; let raw_len: [u8; 4] = input[8..12] .try_into() .expect("We know that the input buffer is at least 16 bytes large"); diff --git a/src/frame.rs b/src/frame.rs index 14f4654..7913400 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -5,20 +5,33 @@ pub struct Frame<'b> { pub inner: std::borrow::Cow<'b, [u8]>, } +#[derive(Debug)] +pub enum FrameParseError { + ParseVarint(()), + NotEnoughBytes, + ParseDemoCommand(i32), +} + +#[derive(Debug)] +pub enum FrameDecompressError { + GettingDecompressedLength(snap::Error), + Decompressing(snap::Error), +} + impl<'b> Frame<'b> { - pub fn parse<'ib>(input: &'ib [u8]) -> Result<(&'ib [u8], Self), ()> + pub fn parse<'ib>(input: &'ib [u8]) -> Result<(&'ib [u8], Self), FrameParseError> where 'ib: 'b, { - let (input, raw_cmd) = crate::varint::parse_varint(input)?; - let (input, tick) = crate::varint::parse_varint(input)?; - let (input, size) = crate::varint::parse_varint(input)?; + let (input, raw_cmd) = crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?; + let (input, tick) = crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?; + let (input, size) = crate::varint::parse_varint(input).map_err(FrameParseError::ParseVarint)?; if input.len() < size as usize { - return Err(()); + return Err(FrameParseError::NotEnoughBytes); } - let demo_cmd = crate::DemoCommand::try_from((raw_cmd & !64) as i32).map_err(|e| ())?; + let demo_cmd = crate::DemoCommand::try_from((raw_cmd & !64) as i32).map_err(FrameParseError::ParseDemoCommand)?; Ok(( &input[size as usize..], @@ -39,7 +52,7 @@ impl<'b> Frame<'b> { Some(self.inner.as_ref()) } - pub fn decompress_with_buf<'s, 'buf>(&'s self, buf: &'b mut Vec) -> Result<&'buf [u8], ()> + pub fn decompress_with_buf<'s, 'buf>(&'s self, buf: &'b mut Vec) -> Result<&'buf [u8], FrameDecompressError> where 's: 'buf, { @@ -48,29 +61,27 @@ impl<'b> Frame<'b> { } let uncompressed_len = snap::raw::decompress_len(&self.inner).map_err(|e| { - println!("Getting decompress len"); - () + FrameDecompressError::GettingDecompressedLength(e) })?; buf.resize(uncompressed_len, 0); snap::raw::Decoder::new() .decompress(&self.inner, buf.as_mut_slice()) .map_err(|e| { - println!("Decompressing"); - () + FrameDecompressError::Decompressing(e) })?; Ok(buf.as_slice()) } - pub fn decompress(&mut self) -> Result<(), ()> { + pub fn decompress(&mut self) -> Result<(), FrameDecompressError> { if !self.compressed { return Ok(()); } let decompressed = snap::raw::Decoder::new() - .decompress_vec(&self.inner.as_ref()) - .map_err(|e| ())?; + .decompress_vec(self.inner.as_ref()) + .map_err(FrameDecompressError::Decompressing)?; self.compressed = false; self.inner = std::borrow::Cow::Owned(decompressed); diff --git a/src/lib.rs b/src/lib.rs index ce06f7c..a55183a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ mod container; pub use container::{Container, ParseContainerError}; mod frame; -pub use frame::{Frame, FrameIterator}; +pub use frame::{Frame, FrameIterator, FrameDecompressError, FrameParseError}; mod democmd; pub use democmd::DemoCommand; diff --git a/src/parser.rs b/src/parser.rs index 97a84f1..782c9f6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,4 @@ -use crate::{packet::DemoEvent, DemoCommand, Frame, UserId}; +use crate::{packet::DemoEvent, DemoCommand, Frame, UserId, FrameDecompressError}; mod fieldpath; pub use fieldpath::{FieldPath, Paths}; @@ -13,7 +13,7 @@ pub use entities::EntityFilter; #[derive(Debug)] pub enum FirstPassError { - DecompressFrame, + DecompressFrame(FrameDecompressError), NoDataFrame, DecodeProtobuf(prost::DecodeError), MissingFileHeader, @@ -73,7 +73,6 @@ struct GameEventMapping { #[derive(Debug)] pub struct Class { - class_id: i32, name: String, serializer: sendtables::Serializer, } @@ -111,7 +110,7 @@ where for frame in frames.into_iter() { let data = frame .decompress_with_buf(&mut buffer) - .map_err(|e| FirstPassError::DecompressFrame)?; + .map_err(FirstPassError::DecompressFrame)?; match frame.cmd { DemoCommand::FileHeader => { @@ -205,7 +204,6 @@ where cls_id as u32, Class { name: network_name.to_owned(), - class_id: cls_id, serializer: ser, }, ); @@ -235,7 +233,7 @@ fn parse_fullpacket(data: &[u8]) -> Result { - if raw.has_pvs_vis_bits() > 0 { - if bitreader.read_nbits(2)? & 0x01 == 1 { - continue; - } + if raw.has_pvs_vis_bits() > 0 && bitreader.read_nbits(2)? & 0x01 == 1 { + continue; } let state = update_entity( @@ -385,7 +384,7 @@ fn inner_parse_packet( match event_mapper.mapping.get(&raw.eventid()) { Some((name, keys)) => { - match crate::game_event::EVENT_PARSERS.get(&name) { + match crate::game_event::EVENT_PARSERS.get(name) { Some(parser) => { let parsed = parser.parse(keys.as_slice(), raw.clone())?; @@ -419,11 +418,6 @@ fn inner_parse_packet( crate::netmessagetypes::NetmessageType::CS_UM_RadioText => {} crate::netmessagetypes::NetmessageType::TE_WorldDecal => {} crate::netmessagetypes::NetmessageType::TE_EffectDispatch => {} - crate::netmessagetypes::NetmessageType::CS_UM_PlayerStatsUpdate => { - let raw: crate::csgo_proto::CcsUsrMsgPlayerStatsUpdate = - prost::Message::decode(msg_bytes.as_slice())?; - // dbg!(&raw); - } crate::netmessagetypes::NetmessageType::CS_UM_EndOfMatchAllPlayersData => { let raw: crate::csgo_proto::CcsUsrMsgEndOfMatchAllPlayersData = prost::Message::decode(msg_bytes.as_slice())?; diff --git a/src/parser/decoder.rs b/src/parser/decoder.rs index 37648f0..8dd8167 100644 --- a/src/parser/decoder.rs +++ b/src/parser/decoder.rs @@ -89,7 +89,7 @@ pub fn find_decoder(field: &super::sendtables::ConstructorField, qf_map: &mut Qf } match BASETYPE_DECODERS.get(field.field_type.base_type.as_str()) { - Some(d) => d.clone(), + Some(d) => *d, None => match field.field_type.base_type.as_str() { "float32" => float_decoder(field, qf_map), "Vector" => find_vector_type(3, field, qf_map), @@ -138,7 +138,7 @@ fn float_decoder(field: &super::sendtables::ConstructorField, qf_map: &mut QfMap "m_flSimulationTime" => Decoder::FloatSimulationTimeDecoder, _ => { if field.bitcount <= 0 || field.bitcount >= 32 { - return Decoder::NoscaleDecoder; + Decoder::NoscaleDecoder } else { let qf = QuantalizedFloat::new( field.bitcount as u32, @@ -213,7 +213,7 @@ impl Decoder { impl<'b> crate::bitreader::Bitreader<'b> { pub fn read_bit_coord_pres(&mut self) -> Result { - return Ok(self.read_nbits(20)? as f32 * 360.0 / (1 << 20) as f32 - 180.0); + Ok(self.read_nbits(20)? as f32 * 360.0 / (1 << 20) as f32 - 180.0) } pub fn decode_qfloat( @@ -232,7 +232,7 @@ impl<'b> crate::bitreader::Bitreader<'b> { if ammo > 0 { return Ok(ammo - 1); } - return Ok(ammo); + Ok(ammo) } pub fn decode_uint64(&mut self) -> Result { @@ -306,7 +306,7 @@ impl<'b> crate::bitreader::Bitreader<'b> { Ok(v) } pub fn read_angle(&mut self, n: usize) -> Result { - return Ok(self.decode_noscale()? / ((1 << n) as f32)); + Ok(self.decode_noscale()? / ((1 << n) as f32)) } pub fn decode_normal(&mut self) -> Result { @@ -331,7 +331,7 @@ impl<'b> crate::bitreader::Bitreader<'b> { let neg_z = self.read_boolean()?; let prod_sum = v[0] * v[0] + v[1] * v[1]; if prod_sum < 1.0 { - v[2] = (1.0 - prod_sum).sqrt() as f32; + v[2] = (1.0 - prod_sum).sqrt(); } else { v[2] = 0.0; } diff --git a/src/parser/decoder/quantizedfloat.rs b/src/parser/decoder/quantizedfloat.rs index efabece..b8b8584 100644 --- a/src/parser/decoder/quantizedfloat.rs +++ b/src/parser/decoder/quantizedfloat.rs @@ -182,25 +182,19 @@ impl QuantalizedFloat { steps = 1 << qf.bit_count; } qf.offset = range_2 as f32 / steps as f32; - qf.high = qf.low + ((range_2 as f32 - qf.offset) as f32); + qf.high = qf.low + (range_2 as f32 - qf.offset); } qf.assign_multipliers(steps); - if (qf.flags & QFF_ROUNDDOWN) != 0 { - if qf.quantize(qf.low) == qf.low { - qf.flags &= !QFF_ROUNDDOWN; - } + if (qf.flags & QFF_ROUNDDOWN) != 0 && qf.quantize(qf.low) == qf.low { + qf.flags &= !QFF_ROUNDDOWN; } - if (qf.flags & QFF_ROUNDUP) != 0 { - if qf.quantize(qf.high) == qf.high { - qf.flags &= !QFF_ROUNDUP - } + if (qf.flags & QFF_ROUNDUP) != 0 && qf.quantize(qf.high) == qf.high { + qf.flags &= !QFF_ROUNDUP } - if (qf.flags & QFF_ENCODE_ZERO) != 0 { - if qf.quantize(0.0) == 0.0 { - qf.flags &= !QFF_ENCODE_ZERO; - } + if (qf.flags & QFF_ENCODE_ZERO) != 0 && qf.quantize(0.0) == 0.0 { + qf.flags &= !QFF_ENCODE_ZERO; } qf diff --git a/src/parser/fieldpath.rs b/src/parser/fieldpath.rs index 9a79f56..9537160 100644 --- a/src/parser/fieldpath.rs +++ b/src/parser/fieldpath.rs @@ -7,6 +7,12 @@ pub struct FieldPath { pub last: usize, } +impl Default for Paths { + fn default() -> Self { + Self::new() + } +} + impl Paths { pub fn new() -> Self { Self(Vec::new()) diff --git a/src/parser/propcontroller.rs b/src/parser/propcontroller.rs index 593cdbb..11c61d5 100644 --- a/src/parser/propcontroller.rs +++ b/src/parser/propcontroller.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + pub const PLAYER_ENTITY_HANDLE_MISSING: i32 = 2047; pub const SPECTATOR_TEAM_NUM: u32 = 1; pub const BUTTONS_BASEID: u32 = 100000; @@ -136,11 +138,8 @@ impl PropController { path.clone(), ); } - Field::Array(ser) => match &mut ser.field_enum.as_mut() { - Field::Value(v) => { - self.handle_prop(&(ser_name.clone() + "." + &v.name), v, path); - } - _ => {} + Field::Array(ser) => if let Field::Value(v) = &mut ser.field_enum.as_mut() { + self.handle_prop(&(ser_name.clone() + "." + &v.name), v, path); }, Field::Vector(_x) => { let vec_path = path.clone(); @@ -150,17 +149,14 @@ impl PropController { for (inner_idx, f) in &mut s.serializer.fields.iter_mut().enumerate() { - match f { - Field::Value(v) => { - let mut myp = vec_path.clone(); - myp.push(inner_idx as i32); - self.handle_prop( - &(ser_name.clone() + "." + &v.name), - v, - myp, - ); - } - _ => {} + if let Field::Value(v) = f { + let mut myp = vec_path.clone(); + myp.push(inner_idx as i32); + self.handle_prop( + &(ser_name.clone() + "." + &v.name), + v, + myp, + ); } } self.traverse_fields( @@ -219,53 +215,50 @@ impl PropController { self.path_to_name.insert(a, prop_name.to_string()); let prop_already_exists = self.name_to_id.contains_key(&(prop_name).to_string()); - self.set_id(&prop_name, f, is_grenade_or_weapon); + self.set_id(&prop_name, f); if !prop_already_exists { self.insert_propinfo(&prop_name, f); } f.should_parse = true; if full_name == "CCSPlayerPawn.CCSPlayer_WeaponServices.m_hMyWeapons" { - f.prop_id = MY_WEAPONS_OFFSET as u32; + f.prop_id = MY_WEAPONS_OFFSET; } if full_name == "CCSPlayerPawn.CCSPlayer_ActionTrackingServices.WeaponPurchaseCount_t.m_nCount" { - f.prop_id = ITEM_PURCHASE_COUNT as u32; + f.prop_id = ITEM_PURCHASE_COUNT; } if full_name == "CCSPlayerPawn.CCSPlayer_BuyServices.SellbackPurchaseEntry_t.m_unDefIdx" { - f.prop_id = ITEM_PURCHASE_DEF_IDX as u32; + f.prop_id = ITEM_PURCHASE_DEF_IDX; } if full_name == "CCSPlayerPawn.CCSPlayer_BuyServices.SellbackPurchaseEntry_t.m_nCost" { - f.prop_id = ITEM_PURCHASE_COST as u32; + f.prop_id = ITEM_PURCHASE_COST; } if full_name == "CCSPlayerPawn.CCSPlayer_ActionTrackingServices.WeaponPurchaseCount_t.m_nItemDefIndex" { - f.prop_id = ITEM_PURCHASE_NEW_DEF_IDX as u32; + f.prop_id = ITEM_PURCHASE_NEW_DEF_IDX; } if full_name == "CCSPlayerPawn.CCSPlayer_BuyServices.SellbackPurchaseEntry_t.m_hItem" { - f.prop_id = ITEM_PURCHASE_HANDLE as u32; + f.prop_id = ITEM_PURCHASE_HANDLE; } if prop_name.contains("CEconItemAttribute.m_iRawValue32") { - f.prop_id = WEAPON_SKIN_ID as u32; + f.prop_id = WEAPON_SKIN_ID; } self.id += 1; } - fn set_id(&mut self, weap_prop: &str, f: &mut ValueField, is_grenade_or_weapon: bool) { + fn set_id(&mut self, weap_prop: &str, f: &mut ValueField) { match self.name_to_id.get(weap_prop) { // If we already have an id for prop of same name then use that id. // Mainly for weapon props. For example CAK47.m_iClip1 and CWeaponSCAR20.m_iClip1 // are the "same" prop. (they have same path and we want to refer to it with one id not ~20) Some(id) => { - f.prop_id = *id as u32; + f.prop_id = *id; self.id_to_name.insert(*id, weap_prop.to_string()); - self.set_special_ids(&weap_prop, is_grenade_or_weapon, *id); - return; } None => { self.name_to_id.insert(weap_prop.to_string(), self.id); self.id_to_name.insert(self.id, weap_prop.to_string()); - f.prop_id = self.id as u32; - self.set_special_ids(&weap_prop, is_grenade_or_weapon, self.id); + f.prop_id = self.id; } } } @@ -274,24 +267,11 @@ impl PropController { self.prop_infos.insert( f.prop_id, PropInfo { - id: f.prop_id as u32, + id: f.prop_id, prop_name: prop_name.into(), }, ); } - - pub fn set_special_ids(&mut self, weap_prop: &str, is_grenade_or_weapon: bool, id: u32) { - // TODO - if is_grenade_or_weapon { - match weap_prop { - _ => {} - }; - } else { - match weap_prop { - _ => {} - }; - } - } } impl SpecialIDs { diff --git a/src/parser/sendtables.rs b/src/parser/sendtables.rs index 4837f4c..5a6d72b 100644 --- a/src/parser/sendtables.rs +++ b/src/parser/sendtables.rs @@ -1,8 +1,5 @@ use super::decoder; -#[derive(Debug)] -pub enum ParseSendTables {} - #[derive(Debug, Clone, PartialEq)] pub struct Serializer { pub name: String, @@ -138,7 +135,7 @@ fn generate_field_data( ) -> Result { let name = msg.symbols.get(field.var_type_sym() as usize).unwrap(); - let ft = find_field_type(&name, field_type_map)?; + let ft = find_field_type(name, field_type_map)?; let mut field = field_from_msg(field, msg, ft.clone())?; field.category = find_category(&field); @@ -166,7 +163,7 @@ fn generate_field_data( fn generate_serializer( serializer: &crate::csgo_proto::ProtoFlattenedSerializerT, - field_data: &mut Vec>, + field_data: &mut [Option], msg: &crate::csgo_proto::CsvcMsgFlattenedSerializer, serializers: &mut std::collections::HashMap, ) -> Result { @@ -188,7 +185,7 @@ fn generate_serializer( }; if f.field_enum_type.is_none() { - f.field_enum_type = Some(create_field(&symbol, f, serializers)?); + f.field_enum_type = Some(create_field(f, serializers)?); } if let Some(Some(f)) = &field_data.get(fi) { if let Some(field) = &f.field_enum_type { @@ -221,6 +218,7 @@ pub enum FieldCategory { } #[derive(Debug, Clone)] +#[allow(dead_code)] pub struct ConstructorField { pub var_name: String, pub var_type: String, @@ -245,7 +243,7 @@ static RE: std::sync::LazyLock = std::sync::LazyLock::new(|| { regex::Regex::new(r"([^<\[\*]+)(<\s(.*)\s>)?(\*)?(\[(.*)\])?").unwrap() }); -const POINTER_TYPES: &'static [&'static str] = &[ +const POINTER_TYPES: &[&str] = &[ "CBodyComponent", "CLightComponent", "CPhysicsComponent", @@ -417,7 +415,7 @@ impl FieldType { if let Some(gt) = self.generic_type.as_ref() { s += "< "; - s += &FieldType::to_string(>, true); + s += &FieldType::to_string(gt, true); s += "< "; } if self.pointer { @@ -450,7 +448,6 @@ fn for_string( } fn create_field( - symbol: &String, fd: &mut ConstructorField, serializers: &mut std::collections::HashMap, ) -> Result { @@ -578,7 +575,8 @@ impl Field { fi.prop_id = ITEM_PURCHASE_NEW_DEF_IDX + path.path[2] as u32; } } - return Some(fi); + + Some(fi) } pub fn get_decoder(&self) -> Result { diff --git a/src/values.rs b/src/values.rs index 2758f82..2c50742 100644 --- a/src/values.rs +++ b/src/values.rs @@ -17,12 +17,12 @@ impl TryFrom for RawVa 1 if value.val_string.is_some() => Ok(Self::String(value.val_string.unwrap())), 2 if value.val_float.is_some() => Ok(Self::F32(value.val_float.unwrap())), 3 if value.val_long.is_some() => Ok(Self::I32(value.val_long.unwrap())), - 4 if value.val_short.is_some() => Ok(Self::I32(value.val_short.unwrap() as i32)), - 5 if value.val_byte.is_some() => Ok(Self::I32(value.val_byte.unwrap() as i32)), + 4 if value.val_short.is_some() => Ok(Self::I32(value.val_short.unwrap())), + 5 if value.val_byte.is_some() => Ok(Self::I32(value.val_byte.unwrap())), 6 if value.val_bool.is_some() => Ok(Self::Bool(value.val_bool.unwrap())), 7 if value.val_uint64.is_some() => Ok(Self::U64(value.val_uint64.unwrap())), 8 if value.val_long.is_some() => Ok(Self::I32(value.val_long.unwrap())), - 9 if value.val_short.is_some() => Ok(Self::I32(value.val_short.unwrap() as i32)), + 9 if value.val_short.is_some() => Ok(Self::I32(value.val_short.unwrap())), _ => Err(()), } } diff --git a/tests/parse.rs b/tests/parse.rs index bdf1e2c..b513459 100644 --- a/tests/parse.rs +++ b/tests/parse.rs @@ -18,25 +18,19 @@ fn mirage_1() { assert_eq!("de_mirage", output.header.map_name()); for event in output.events.iter() { - match event { - DemoEvent::GameEvent(gevent) => match gevent { - GameEvent::PlayerDeath(death) => { - assert!( - death.remaining.is_empty(), - "Remaining for PlayerDeath: {:?}", - death.remaining - ); + if let DemoEvent::GameEvent(gevent) = event { if let GameEvent::PlayerDeath(death) = gevent { + assert!( + death.remaining.is_empty(), + "Remaining for PlayerDeath: {:?}", + death.remaining + ); - let died_user = output - .player_info - .get(death.userid.as_ref().unwrap()) - .unwrap(); - // dbg!(died_user); - } - _ => {} - }, - _ => {} - }; + let died_user = output + .player_info + .get(death.userid.as_ref().unwrap()) + .unwrap(); + // dbg!(died_user); + } }; } todo!()