faster raw subject

This commit is contained in:
Robin Appelman 2021-08-29 13:54:22 +02:00
commit c215ca3987
3 changed files with 40 additions and 69 deletions

View file

@ -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,

View file

@ -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)?;

View file

@ -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)]