more edge case handling

This commit is contained in:
Robin Appelman 2023-03-16 21:44:41 +01:00
commit f1213a5664
5 changed files with 15 additions and 9 deletions

View file

@ -138,7 +138,8 @@ impl<'a> Iterator for ParamIter<'a> {
fn param_pair_parse(input: &str) -> IResult<'_, (&str, &str)> {
let (input, open_tag) = skip_matches(input, b'(');
let (key, input) = split_once(input, b' ', 2)?;
let (key, input) = split_once(input, b' ', 1)?;
let input = skip(input, 1)?;
let (value, input) = split_once(input, b'"', 1)?;
let input = if open_tag { skip(input, 1)? } else { input };

View file

@ -18,7 +18,7 @@ pub struct ShotHitEvent<'a> {
#[derive(Debug, Event)]
pub struct DamageEvent<'a> {
#[event(name = "against")]
pub target: RawSubject<'a>,
pub target: Option<RawSubject<'a>>,
pub damage: Option<NonZeroU32>,
#[event(name = "realdamage")]
pub real_damage: Option<NonZeroU32>,

View file

@ -93,7 +93,7 @@ impl EventHandler for ClassStatsHandler {
}
GameEvent::Damage(DamageEvent {
damage: Some(damage),
target,
target: Some(target),
..
}) if self.active => {
if let Some(target_class) = self.get_class(target) {

View file

@ -5,6 +5,7 @@ use once_cell::unsync::Lazy;
pub fn split_once(input: &str, delim: u8, offset: usize) -> Result<(&str, &str)> {
debug_assert!(delim < 128); // only basic ascii
debug_assert!(offset <= 1);
let end = memchr(delim, input.as_bytes()).ok_or(Error::Incomplete)?;
// safety, memchr returns indices that are inside the input length and we only split on ascii
Ok(unsafe {
@ -22,6 +23,7 @@ thread_local! {
pub fn split_subject_end<'a>(input: &'a str, offset: usize) -> Result<(&'a str, &'a str)> {
let start_offset = 1;
let end_offset = start_offset + offset;
debug_assert!(offset <= 2);
let end = SUBJECT_END_FINDER
.with(|finder| finder.find(input.as_bytes()))
.ok_or(Error::Incomplete)?;

View file

@ -1,5 +1,5 @@
use crate::common::Team;
use crate::parsing::{split_once, split_subject_end};
use crate::parsing::{skip, split_once, split_subject_end};
use crate::{Error, Result};
use crate::{SubjectError, SubjectId};
use chrono::{NaiveDate, NaiveDateTime};
@ -19,7 +19,6 @@ pub struct RawEvent<'a> {
impl<'a> RawEvent<'a> {
pub fn parse(line: &'a str) -> Result<Self> {
debug_assert!(!line.ends_with("\n"));
event_parser(line)
}
}
@ -29,7 +28,7 @@ fn event_parser(input: &str) -> Result<RawEvent> {
let (input, subject) = subject_parser(&input[23..])?;
let (input, ty) = event_type_parser(&input[1..])?;
let (input, ty) = event_type_parser(input)?;
let params = &input[(!input.is_empty() as usize)..];
@ -133,6 +132,7 @@ pub fn subject_parser(input: &str) -> Result<(&str, RawSubject)> {
let Ok((player, input)) = split_subject_end(input, 1) else {
return Ok((full, RawSubject::Console))
};
let input = skip(input, 1)?;
if player.ends_with("le>") {
Ok((input, RawSubject::Console))
} else {
@ -141,15 +141,18 @@ pub fn subject_parser(input: &str) -> Result<(&str, RawSubject)> {
} else if input.starts_with("Te") {
// Team "red" or Team "blue"
if &input[6..7] == "r" {
Ok((&input[10..], RawSubject::Team(Team::Red)))
Ok((&input[11..], RawSubject::Team(Team::Red)))
} else if &input[6..7] == "b" {
Ok((&input[11..], RawSubject::Team(Team::Blue)))
Ok((&input[12..], RawSubject::Team(Team::Blue)))
} else {
let (_, input) = split_once(&input[7..], b'"', 1)?;
let input = skip(input, 1)?;
Ok((input, RawSubject::Team(Team::Spectator)))
}
} else {
let (system, input) = split_once(input, b' ', 0)?;
let Ok((system, input)) = split_once(input, b' ', 1) else {
return Ok(("", RawSubject::System(input)))
};
Ok((input, RawSubject::System(system)))
}
}