try out logos

This commit is contained in:
Robin Appelman 2021-08-28 18:09:47 +02:00
commit d09e60aa18
2 changed files with 68 additions and 76 deletions

View file

@ -17,6 +17,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
main_error = "0.1" main_error = "0.1"
paste = "1" paste = "1"
logos = { version = "0.12", path = "../../logos/logos" }
[dev-dependencies] [dev-dependencies]
criterion = "0.3" criterion = "0.3"

View file

@ -1,10 +1,9 @@
use crate::{SubjectError, SubjectId}; use crate::{SubjectError, SubjectId};
use chrono::{DateTime, TimeZone, Utc}; use chrono::{DateTime, TimeZone, Utc};
use enum_iterator::IntoEnumIterator; use logos::{Lexer, Logos};
use nom::branch::alt; use nom::branch::alt;
use nom::bytes::complete::{tag, tag_no_case, take_while}; use nom::bytes::complete::{tag, tag_no_case, take_while};
use nom::character::complete::{digit1, one_of}; use nom::character::complete::{digit1, one_of};
use nom::error::{make_error, ErrorKind};
use nom::{Finish, IResult}; use nom::{Finish, IResult};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::num::ParseIntError; use std::num::ParseIntError;
@ -187,146 +186,138 @@ pub fn subject_parser(input: &str) -> IResult<&str, RawSubject> {
))(input) ))(input)
} }
#[derive(IntoEnumIterator, Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq, Logos)]
pub enum RawEventType { pub enum RawEventType {
#[token(r#"joined"#)]
Joined, Joined,
#[token(r#"changed role"#)]
ChangedRole, ChangedRole,
#[token(r#"triggered "shot_fired""#)]
ShotFired, ShotFired,
#[token(r#"triggered "shot_hit""#)]
ShotHit, ShotHit,
#[token(r#"triggered "damage""#)]
Damage, Damage,
#[token(r#"triggered "healed""#)]
Healed, Healed,
#[token(r#"triggered "first_heal_after_spawn""#)]
FirstHealAfterSpawn, FirstHealAfterSpawn,
#[token(r#"killed"#)]
Killed, Killed,
#[token(r#"triggered "kill assist""#)]
KillAssist, KillAssist,
#[token(r#"committed suicide"#)]
Suicide, Suicide,
#[token(r#"triggered "domination""#)]
Domination, Domination,
#[token(r#"triggered "revenge""#)]
Revenge, Revenge,
#[token(r#"spawned"#)]
Spawned, Spawned,
#[token(r#"say_team"#)]
SayTeam, SayTeam,
#[token(r#"say"#)]
Say, Say,
#[token(r#"triggered "empty_uber""#)]
EmptyUber, EmptyUber,
#[token(r#"triggered "player_builtobject""#)]
PlayerBuiltObject, PlayerBuiltObject,
#[token(r#"triggered "player_dropobject""#)]
PlayerCarryObject, PlayerCarryObject,
#[token(r#"triggered "player_carryobject""#)]
PlayerDropObject, PlayerDropObject,
#[token(r#"triggered "killedobject""#)]
PlayerKilledObject, PlayerKilledObject,
#[token(r#"triggered "object_detonated""#)]
PlayerExtinguished, PlayerExtinguished,
#[token(r#"triggered "player_extinguished""#)]
ObjectDetonated, ObjectDetonated,
#[token(r#"picked up"#)]
PickedUp, PickedUp,
#[token(r#"triggered "medic_death""#)]
MedicDeath, MedicDeath,
#[token(r#"triggered "medic_death_ex""#)]
MedicDeathEx, MedicDeathEx,
#[token(r#"triggered "chargeended""#)]
ChargeEnd, ChargeEnd,
#[token(r#"triggered "chargeready""#)]
ChargeReady, ChargeReady,
#[token(r#"triggered "chargedeployed""#)]
ChargeDeployed, ChargeDeployed,
#[token(r#"triggered "lost_uber_advantage""#)]
UberAdvantageLost, UberAdvantageLost,
#[token(r#"triggered "Round_Start""#)]
RoundStart, RoundStart,
#[token(r#"triggered "Round_Setup_Begin""#)]
RoundSetupBegin, RoundSetupBegin,
#[token(r#"triggered "Round_Setup_End""#)]
RoundSetupEnd, RoundSetupEnd,
#[token(r#"triggered "Mini_Round_Selected""#)]
MiniRoundSelected, MiniRoundSelected,
#[token(r#"triggered "Mini_Round_Start""#)]
MiniRoundStart, MiniRoundStart,
#[token(r#"triggered "Round_Win""#)]
RoundWin, RoundWin,
#[token(r#"triggered "Mini_Round_Win""#)]
MiniRoundWin, MiniRoundWin,
#[token(r#"triggered "Round_Length""#)]
RoundLength, RoundLength,
#[token(r#"triggered "Mini_Round_Length""#)]
MiniRoundLength, MiniRoundLength,
#[token(r#"triggered "Round_Overtime""#)]
RoundOvertime, RoundOvertime,
#[token(r#"triggered "pointcaptured""#)]
PointCaptured, PointCaptured,
#[token(r#"triggered "captureblocked""#)]
CaptureBlocked, CaptureBlocked,
#[token(r#"triggered "Game_Over""#)]
GameOver, GameOver,
#[token(r#"current"#)]
CurrentScore, CurrentScore,
#[token(r#"final"#)]
FinalScore, FinalScore,
#[token(r#"triggered "Intermission_Win_Limit""#)]
WinLimit, WinLimit,
#[token(r#"triggered "Game_Paused""#)]
Paused, Paused,
#[token(r#"triggered "Game_Unpaused""#)]
UnPaused, UnPaused,
#[token(r#"Request: "#)]
Request, Request,
#[token(r#"Response: "#)]
Response, Response,
#[token(r#"connected,"#)]
Connected, Connected,
#[token(r#"disconnected"#)]
Disconnected, Disconnected,
#[token(r#"STEAM USERID validated"#)]
SteamIdValidated, SteamIdValidated,
#[token(r#"entered the game"#)]
Entered, Entered,
#[token(r#"file started"#)]
LogFileStarted, LogFileStarted,
#[token(r#"file closed"#)]
LogFileClosed, LogFileClosed,
#[token(r#"The log might have not been uploaded."#)]
NotUploaded, NotUploaded,
#[token(r#"mode started"#)]
TournamentStart, TournamentStart,
#[token(r#"triggered "flagevent""#)]
FlagEvent, FlagEvent,
} #[error]
Unknown,
impl RawEventType {
pub fn tag(self) -> &'static str {
match self {
RawEventType::Joined => r#"joined"#,
RawEventType::ChangedRole => r#"changed role"#,
RawEventType::ShotFired => r#"triggered "shot_fired""#,
RawEventType::ShotHit => r#"triggered "shot_hit""#,
RawEventType::Damage => r#"triggered "damage""#,
RawEventType::Healed => r#"triggered "healed""#,
RawEventType::FirstHealAfterSpawn => r#"triggered "first_heal_after_spawn""#,
RawEventType::Killed => r#"killed"#,
RawEventType::KillAssist => r#"triggered "kill assist""#,
RawEventType::Suicide => r#"committed suicide"#,
RawEventType::Domination => r#"triggered "domination""#,
RawEventType::Revenge => r#"triggered "revenge""#,
RawEventType::Spawned => r#"spawned"#,
RawEventType::SayTeam => r#"say_team"#,
RawEventType::Say => r#"say"#,
RawEventType::EmptyUber => r#"triggered "empty_uber""#,
RawEventType::PlayerBuiltObject => r#"triggered "player_builtobject""#,
RawEventType::PlayerDropObject => r#"triggered "player_dropobject""#,
RawEventType::PlayerCarryObject => r#"triggered "player_carryobject""#,
RawEventType::PlayerKilledObject => r#"triggered "killedobject""#,
RawEventType::ObjectDetonated => r#"triggered "object_detonated""#,
RawEventType::PlayerExtinguished => r#"triggered "player_extinguished""#,
RawEventType::PickedUp => r#"picked up"#,
RawEventType::MedicDeath => r#"triggered "medic_death""#,
RawEventType::MedicDeathEx => r#"triggered "medic_death_ex""#,
RawEventType::ChargeEnd => r#"triggered "chargeended""#,
RawEventType::ChargeReady => r#"triggered "chargeready""#,
RawEventType::ChargeDeployed => r#"triggered "chargedeployed""#,
RawEventType::UberAdvantageLost => r#"triggered "lost_uber_advantage""#,
RawEventType::RoundStart => r#"triggered "Round_Start""#,
RawEventType::RoundSetupBegin => r#"triggered "Round_Setup_Begin""#,
RawEventType::RoundSetupEnd => r#"triggered "Round_Setup_End""#,
RawEventType::MiniRoundSelected => r#"triggered "Mini_Round_Selected""#,
RawEventType::MiniRoundStart => r#"triggered "Mini_Round_Start""#,
RawEventType::RoundWin => r#"triggered "Round_Win""#,
RawEventType::MiniRoundWin => r#"triggered "Mini_Round_Win""#,
RawEventType::RoundLength => r#"triggered "Round_Length""#,
RawEventType::MiniRoundLength => r#"triggered "Mini_Round_Length""#,
RawEventType::RoundOvertime => r#"triggered "Round_Overtime""#,
RawEventType::PointCaptured => r#"triggered "pointcaptured""#,
RawEventType::CaptureBlocked => r#"triggered "captureblocked""#,
RawEventType::GameOver => r#"triggered "Game_Over""#,
RawEventType::CurrentScore => r#"current"#,
RawEventType::FinalScore => r#"final"#,
RawEventType::WinLimit => r#"triggered "Intermission_Win_Limit""#,
RawEventType::Paused => r#"triggered "Game_Paused""#,
RawEventType::UnPaused => r#"triggered "Game_Unpaused""#,
RawEventType::Request => r#"Request: "#,
RawEventType::Response => r#"Response: "#,
RawEventType::Connected => r#"connected,"#,
RawEventType::Disconnected => r#"disconnected"#,
RawEventType::SteamIdValidated => r#"STEAM USERID validated"#,
RawEventType::Entered => r#"entered the game"#,
RawEventType::LogFileStarted => r#"file started"#,
RawEventType::LogFileClosed => r#"file closed"#,
RawEventType::NotUploaded => r#"The log might have not been uploaded."#,
RawEventType::TournamentStart => r#"mode started"#,
RawEventType::FlagEvent => r#"triggered "flagevent""#,
}
}
} }
fn event_type_parser(input: &str) -> IResult<&str, RawEventType> { fn event_type_parser(input: &str) -> IResult<&str, RawEventType> {
for event_type in RawEventType::into_enum_iter() { let mut lexer = Lexer::new(input);
if let Ok((input, _ty)) = tag::<_, _, nom::error::Error<&str>>(event_type.tag())(input) { let ty = lexer.next().unwrap_or(RawEventType::Unknown);
return Ok((input, event_type)); Ok((lexer.remainder(), ty))
}
}
Err(nom::Err::Error(make_error(input, ErrorKind::NoneOf)))
} }
#[test] #[test]
fn test_parse_raw() { fn test_parse_raw() {
let input = let input =
r#"L 08/06/2018 - 21:13:57: "makxbi<27><[U:1:40364391]><Red>" changed role to "sniper""#; r#"08/06/2018 - 21:13:57: "makxbi<27><[U:1:40364391]><Red>" changed role to "sniper""#;
let raw = RawEvent::parse(input).unwrap(); let raw = RawEvent::parse(input).unwrap();
assert_eq!( assert_eq!(
RawEvent { RawEvent {
@ -365,7 +356,7 @@ fn test_parse_all_valid() {
.unwrap() .unwrap()
.read_to_string(&mut buff) .read_to_string(&mut buff)
.unwrap(); .unwrap();
for line in buff.trim().lines() { for line in buff.trim().split("L ").filter(|line| !line.is_empty()) {
if line.starts_with("L ") { if line.starts_with("L ") {
RawEvent::parse(line).unwrap(); RawEvent::parse(line).unwrap();
} }