mirror of
https://codeberg.org/icewind/tf-log-parser.git
synced 2026-06-03 10:14:10 +02:00
faster raw subject
This commit is contained in:
parent
a4653ab04b
commit
c215ca3987
3 changed files with 40 additions and 69 deletions
|
|
@ -213,9 +213,7 @@ impl TryFrom<&RawSubject<'_>> for SubjectId {
|
|||
return Err(SubjectError::InvalidSteamId);
|
||||
}
|
||||
}
|
||||
RawSubject::Team(team) => {
|
||||
SubjectId::Team(team.parse().map_err(|_| SubjectError::InvalidTeam)?)
|
||||
}
|
||||
RawSubject::Team(team) => SubjectId::Team(*team),
|
||||
RawSubject::System(_) => SubjectId::System,
|
||||
RawSubject::Console => SubjectId::Console,
|
||||
RawSubject::World => SubjectId::World,
|
||||
|
|
@ -275,7 +273,7 @@ impl TryFrom<&RawSubject<'_>> for SubjectData {
|
|||
team: team.parse().map_err(|_| SubjectError::InvalidTeam)?,
|
||||
}
|
||||
}
|
||||
RawSubject::Team(team) => SubjectData::Team(team.parse().unwrap()),
|
||||
RawSubject::Team(team) => SubjectData::Team(*team),
|
||||
RawSubject::System(name) => SubjectData::System(name.to_string()),
|
||||
RawSubject::Console => SubjectData::Console,
|
||||
RawSubject::World => SubjectData::World,
|
||||
|
|
|
|||
|
|
@ -87,14 +87,16 @@ impl<Head: EventHandler, Tail: EventHandler> EventHandler for HandlerStack<Head,
|
|||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! replace_expr {
|
||||
($_t:tt $sub:expr) => {
|
||||
$sub
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! count_tts {
|
||||
($($tts:tt)*) => {0usize $(+ replace_expr!($tts 1usize))*};
|
||||
($($tts:tt)*) => {0usize $(+ $crate::replace_expr!($tts 1usize))*};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
|
@ -119,7 +121,7 @@ macro_rules! handler {
|
|||
S: serde::Serializer,
|
||||
{
|
||||
use serde::ser::SerializeStruct;
|
||||
let mut state = serializer.serialize_struct(concat!(stringify!($name), "output"), count_tts!($($child)*))?;
|
||||
let mut state = serializer.serialize_struct(concat!(stringify!($name), "output"), $crate::count_tts!($($child)*))?;
|
||||
$(
|
||||
if self.$child != <<$ty as $crate::EventHandler>::GlobalOutput>::default() {
|
||||
state.serialize_field(stringify!($child), &self.$child)?;
|
||||
|
|
@ -151,7 +153,7 @@ macro_rules! handler {
|
|||
S: serde::Serializer,
|
||||
{
|
||||
use serde::ser::SerializeStruct;
|
||||
let mut state = serializer.serialize_struct(concat!(stringify!($name), "output"), count_tts!($($child)*))?;
|
||||
let mut state = serializer.serialize_struct(concat!(stringify!($name), "output"), $crate::count_tts!($($child)*))?;
|
||||
$(
|
||||
if self.$child != <<$ty as $crate::EventHandler>::PerSubjectOutput>::default() {
|
||||
state.serialize_field(stringify!($child), &self.$child)?;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use crate::common::Team;
|
||||
use crate::{SubjectError, SubjectId};
|
||||
use chrono::{NaiveDate, NaiveDateTime};
|
||||
use logos::{Lexer, Logos};
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{tag, tag_no_case, take, take_while};
|
||||
use nom::bytes::complete::{tag, take, take_while};
|
||||
use nom::character::complete::{digit1, one_of};
|
||||
use nom::{Finish, IResult};
|
||||
use nom::combinator::opt;
|
||||
use nom::{Finish, IResult, Needed};
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::num::ParseIntError;
|
||||
|
||||
|
|
@ -18,13 +19,6 @@ pub struct RawEvent<'a> {
|
|||
pub params: &'a str,
|
||||
}
|
||||
|
||||
// pub enum RawEventToken {
|
||||
// #[error]
|
||||
// Error,
|
||||
// #[regex(r"\d{2}/\d{2}/\d{4} - \d{2}:\d{2}:\d{2}"), |raw| NaiveDateTime::parse_from_str(raw, "%m/$d/%Y - %H:%M%S")]
|
||||
// Date(NaiveDateTime),
|
||||
// }
|
||||
|
||||
impl<'a> RawEvent<'a> {
|
||||
pub fn parse(line: &'a str) -> Result<Self, nom::error::Error<&'a str>> {
|
||||
let (_, event) = event_parser(line).finish()?;
|
||||
|
|
@ -38,7 +32,7 @@ fn event_parser(input: &str) -> IResult<&str, RawEvent> {
|
|||
let (input, _) = tag(": ")(input)?;
|
||||
let (input, subject) = subject_parser(input)?;
|
||||
|
||||
let (input, _) = tag(" ")(input)?;
|
||||
let (input, _) = opt(tag(" "))(input)?;
|
||||
let (input, ty) = event_type_parser(input)?;
|
||||
|
||||
Ok((
|
||||
|
|
@ -87,7 +81,7 @@ fn test_parse_date() {
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub enum RawSubject<'a> {
|
||||
Player(&'a str),
|
||||
Team(&'a str),
|
||||
Team(Team),
|
||||
System(&'a str),
|
||||
Console,
|
||||
World,
|
||||
|
|
@ -99,39 +93,6 @@ impl<'a> RawSubject<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn subject_parser_world(input: &str) -> IResult<&str, RawSubject> {
|
||||
let (input, _) = tag("World")(input)?;
|
||||
Ok((input, RawSubject::World))
|
||||
}
|
||||
|
||||
fn subject_parser_console(input: &str) -> IResult<&str, RawSubject> {
|
||||
let (input, _) = tag(r#""Console<0><Console><Console>""#)(input)?;
|
||||
Ok((input, RawSubject::Console))
|
||||
}
|
||||
|
||||
fn subject_parser_team(input: &str) -> IResult<&str, RawSubject> {
|
||||
let (input, _) = tag(r#"Team ""#)(input)?;
|
||||
|
||||
let (input, team) = alt((tag_no_case("red"), tag_no_case("blue")))(input)?;
|
||||
|
||||
let (input, _) = one_of("\"")(input)?;
|
||||
Ok((input, RawSubject::Team(team)))
|
||||
}
|
||||
|
||||
fn subject_parser_system_bracket(input: &str) -> IResult<&str, &str> {
|
||||
let (input, _) = tag("[")(input)?;
|
||||
|
||||
let (input, name) = take_while(|c| c != ']')(input)?;
|
||||
|
||||
let (input, _) = tag("]")(input)?;
|
||||
IResult::Ok((input, name))
|
||||
}
|
||||
|
||||
fn subject_parser_system(input: &str) -> IResult<&str, RawSubject> {
|
||||
let (input, name) = alt((subject_parser_system_bracket, tag("Log"), tag("Tournament")))(input)?;
|
||||
Ok((input, RawSubject::System(name)))
|
||||
}
|
||||
|
||||
pub fn split_player_subject(input: &str) -> IResult<&str, (&str, &str, &str, &str)> {
|
||||
let (input, name) = take_while(|c| c != '<')(input)?;
|
||||
|
||||
|
|
@ -150,24 +111,34 @@ pub fn split_player_subject(input: &str) -> IResult<&str, (&str, &str, &str, &st
|
|||
Ok((input, (name, user_id, steam_id, team)))
|
||||
}
|
||||
|
||||
fn subject_parser_player(input: &str) -> IResult<&str, RawSubject> {
|
||||
let (input, _) = one_of("\"")(input)?;
|
||||
|
||||
let (input, subject) = take_while(|c| c != '"')(input)?;
|
||||
|
||||
let (input, _) = one_of("\"")(input)?;
|
||||
|
||||
Ok((input, RawSubject::Player(subject)))
|
||||
}
|
||||
|
||||
pub fn subject_parser(input: &str) -> IResult<&str, RawSubject> {
|
||||
alt((
|
||||
subject_parser_console,
|
||||
subject_parser_player,
|
||||
subject_parser_world,
|
||||
subject_parser_team,
|
||||
subject_parser_system,
|
||||
))(input)
|
||||
if input.starts_with('"') {
|
||||
let (player, input) = input[1..]
|
||||
.split_once('"')
|
||||
.ok_or_else(|| nom::Err::Incomplete(Needed::Unknown))?;
|
||||
if player.ends_with("e>") {
|
||||
Ok((input, RawSubject::Console))
|
||||
} else {
|
||||
Ok((input, RawSubject::Player(player)))
|
||||
}
|
||||
} else if input.starts_with("Te") {
|
||||
// Team "red" or Team "blue"
|
||||
if &input[6..7] == "r" {
|
||||
Ok((&input[10..], RawSubject::Team(Team::Red)))
|
||||
} else if &input[6..7] == "b" {
|
||||
Ok((&input[11..], RawSubject::Team(Team::Blue)))
|
||||
} else {
|
||||
let (_, input) = input[7..]
|
||||
.split_once('"')
|
||||
.ok_or_else(|| nom::Err::Incomplete(Needed::Unknown))?;
|
||||
Ok((input, RawSubject::Team(Team::Spectator)))
|
||||
}
|
||||
} else {
|
||||
let (system, input) = input
|
||||
.split_once(' ')
|
||||
.ok_or_else(|| nom::Err::Incomplete(Needed::Unknown))?;
|
||||
Ok((input, RawSubject::System(system)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Logos)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue