move param parsers from IResult to Result

This commit is contained in:
Robin Appelman 2023-03-11 16:11:22 +01:00
commit b138798b53
4 changed files with 33 additions and 72 deletions

View file

@ -54,7 +54,7 @@ impl Derivable for Event {
}; };
Ok(quote_spanned!( Ok(quote_spanned!(
field_name.span() => #param_name => event.#field_name = parse_field(value)?.1 field_name.span() => #param_name => event.#field_name = parse_field(value)?
)) ))
}) })
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;

View file

@ -88,7 +88,7 @@ impl<'a> Event<'a> for PointCapturedEvent<'a> {
if subject_key.starts_with("player") if subject_key.starts_with("player")
&& position_key.starts_with("position") => && position_key.starts_with("position") =>
{ {
players.push((parse_field(subject)?.1, parse_field(position_str)?.1)); players.push((parse_field(subject)?, parse_field(position_str)?));
} }
_ => break, _ => break,
} }

View file

@ -2,10 +2,10 @@ mod game;
mod medic; mod medic;
mod player; mod player;
use crate::common::{skip, skip_matches, split_once, take_until}; use crate::common::{skip, skip_matches, split_once};
use crate::event::game::{RoundLengthEvent, RoundWinEvent}; use crate::event::game::{RoundLengthEvent, RoundWinEvent};
use crate::raw_event::{against_subject_parser, RawSubject}; use crate::raw_event::{against_subject_parser, RawSubject};
use crate::{Error, IResult, RawEvent, RawEventType, SubjectId}; use crate::{Error, IResult, RawEvent, RawEventType, Result, SubjectId};
pub use game::*; pub use game::*;
pub use medic::*; pub use medic::*;
pub use player::*; pub use player::*;
@ -226,13 +226,11 @@ fn param_pair_parse(input: &str) -> IResult<'_, (&str, &str)> {
Ok((input, (key, value))) Ok((input, (key, value)))
} }
fn quoted<'a, T, P: Fn(&'a str) -> IResult<'a, T>>( fn quoted<'a, T, P: Fn(&'a str) -> Result<T>>(parser: P) -> impl Fn(&'a str) -> IResult<'a, T> {
parser: P,
) -> impl Fn(&'a str) -> IResult<'a, T> {
move |input| { move |input| {
let input = skip(input, 1)?; let input = skip(input, 1)?;
let (inner, input) = split_once(input, b'"', 1)?; let (inner, input) = split_once(input, b'"', 1)?;
let (_, res) = parser(inner)?; let res = parser(inner)?;
Ok((input, res)) Ok((input, res))
} }
} }
@ -241,7 +239,7 @@ pub fn param_parse<'a, T: EventField<'a>>(key: &'a str) -> impl Fn(&'a str) -> I
param_parse_with(key, T::parse_field) param_parse_with(key, T::parse_field)
} }
pub fn param_parse_with<'a, T, P: Fn(&'a str) -> IResult<'a, T>>( pub fn param_parse_with<'a, T, P: Fn(&'a str) -> Result<T>>(
key: &'a str, key: &'a str,
parser: P, parser: P,
) -> impl Fn(&'a str) -> IResult<'a, T> { ) -> impl Fn(&'a str) -> IResult<'a, T> {
@ -252,7 +250,7 @@ pub fn param_parse_with<'a, T, P: Fn(&'a str) -> IResult<'a, T>>(
let (value, input) = split_once(input, b'"', 1)?; let (value, input) = split_once(input, b'"', 1)?;
let (_, value) = parser(value)?; let value = parser(value)?;
let input = skip(input, has_open as usize)?; let input = skip(input, has_open as usize)?;
@ -261,100 +259,63 @@ pub fn param_parse_with<'a, T, P: Fn(&'a str) -> IResult<'a, T>>(
} }
} }
fn parse_from_str<'a, T: FromStr + 'a>(input: &'a str) -> IResult<T> { fn parse_from_str<'a, T: FromStr + 'a>(input: &'a str) -> Result<T> {
T::from_str(input) T::from_str(input).map_err(|_| Error::Malformed)
.map(|res| ("", res))
.map_err(|_| Error::Malformed)
}
fn int(input: &str) -> IResult<i32> {
let (input, sign) = skip_matches(input, b'-');
let (input, unsigned) = u_int(input)?;
let signed = unsigned as i32;
Ok((input, if sign { -signed } else { signed }))
}
fn u_int(input: &str) -> IResult<u32> {
let (input, raw) = take_until(input, b' ');
let val = raw.parse().map_err(|_| Error::Incomplete)?;
Ok((input, val))
} }
pub trait EventField<'a>: Sized + 'a { pub trait EventField<'a>: Sized + 'a {
fn parse_field(input: &'a str) -> IResult<Self>; fn parse_field(input: &'a str) -> Result<Self>;
} }
impl<'a> EventField<'a> for &'a str { impl<'a> EventField<'a> for &'a str {
fn parse_field(input: &'a str) -> IResult<Self> { fn parse_field(input: &'a str) -> Result<Self> {
Ok(("", input)) Ok(input)
}
}
impl<'a> EventField<'a> for i32 {
fn parse_field(input: &'a str) -> IResult<Self> {
int(input)
}
}
impl<'a> EventField<'a> for u32 {
fn parse_field(input: &'a str) -> IResult<Self> {
u_int(input)
}
}
impl<'a> EventField<'a> for f32 {
fn parse_field(input: &'a str) -> IResult<Self> {
let (input, raw) = take_until(input, b' ');
Ok((input, raw.parse().map_err(|_| Error::Malformed)?))
}
}
impl<'a> EventField<'a> for u8 {
fn parse_field(input: &'a str) -> IResult<Self> {
u_int(input).map(|(rest, num)| (rest, num as u8))
} }
} }
impl<'a, T: EventField<'a>> EventField<'a> for Option<T> { impl<'a, T: EventField<'a>> EventField<'a> for Option<T> {
fn parse_field(input: &'a str) -> IResult<Self> { fn parse_field(input: &'a str) -> Result<Self> {
T::parse_field(input).map(|(rest, int)| (rest, Some(int))) T::parse_field(input).map(Some)
} }
} }
pub trait EventFieldFromStr: FromStr {} pub trait EventFieldFromStr: FromStr {}
impl<'a, T: EventFieldFromStr + 'a> EventField<'a> for T { impl<'a, T: EventFieldFromStr + 'a> EventField<'a> for T {
fn parse_field(input: &'a str) -> IResult<Self> { fn parse_field(input: &'a str) -> Result<Self> {
parse_from_str(input) parse_from_str(input)
} }
} }
impl EventFieldFromStr for SocketAddr {} impl EventFieldFromStr for SocketAddr {}
impl EventFieldFromStr for u8 {}
impl EventFieldFromStr for u32 {}
impl EventFieldFromStr for i32 {}
impl EventFieldFromStr for f32 {}
impl<'a, T: EventField<'a>> EventField<'a> for (T, T, T) { impl<'a, T: EventField<'a>> EventField<'a> for (T, T, T) {
fn parse_field(input: &'a str) -> IResult<Self> { fn parse_field(input: &'a str) -> Result<Self> {
let (input, x) = parse_field(input)?; let (x, input) = split_once(input, b' ', 1)?;
let input = skip(input, 1)?; let x = parse_field(x)?;
let (input, y) = parse_field(input)?; let (y, input) = split_once(input, b' ', 1)?;
let input = skip(input, 1)?; let y = parse_field(y)?;
let (input, z) = parse_field(input)?; let z = parse_field(input)?;
Ok((input, (x, y, z))) Ok((x, y, z))
} }
} }
impl<'a> EventField<'a> for Option<NonZeroU32> { impl<'a> EventField<'a> for Option<NonZeroU32> {
fn parse_field(input: &'a str) -> IResult<Self> { fn parse_field(input: &'a str) -> Result<Self> {
u32::parse_field(input).map(|(rest, int)| (rest, NonZeroU32::new(int))) u32::parse_field(input).map(|int| NonZeroU32::new(int))
} }
} }
impl<'a> EventField<'a> for RawSubject<'a> { impl<'a> EventField<'a> for RawSubject<'a> {
fn parse_field(input: &'a str) -> IResult<Self> { fn parse_field(input: &'a str) -> Result<Self> {
Ok(("", against_subject_parser(input)?)) against_subject_parser(input)
} }
} }
pub fn parse_field<'a, T: EventField<'a>>(input: &'a str) -> IResult<T> { pub fn parse_field<'a, T: EventField<'a>>(input: &'a str) -> Result<T> {
T::parse_field(input) T::parse_field(input)
} }

View file

@ -40,7 +40,7 @@ impl From<ParseIntError> for Error {
} }
} }
type Result<O, E = Error> = std::result::Result<O, E>; pub type Result<O, E = Error> = std::result::Result<O, E>;
#[doc(hidden)] #[doc(hidden)]
pub type IResult<'a, O, E = Error> = std::result::Result<(&'a str, O), E>; pub type IResult<'a, O, E = Error> = std::result::Result<(&'a str, O), E>;