vbsp_common/
property.rs

1use crate::{Angles, Color, LightColor, Negated, Vector};
2use std::num::{ParseFloatError, ParseIntError};
3use std::str::FromStr;
4use thiserror::Error;
5
6pub trait EntityProp<'a>: Sized {
7    fn parse(raw: &'a str) -> Result<Self, EntityParseError>;
8}
9
10/// Properties that can be parsed with their FromStr implementation
11pub trait FromStrProp: FromStr {}
12
13impl FromStrProp for u8 {}
14impl FromStrProp for u16 {}
15impl FromStrProp for f32 {}
16impl FromStrProp for u32 {}
17impl FromStrProp for i32 {}
18impl FromStrProp for Color {}
19impl FromStrProp for Angles {}
20impl FromStrProp for Vector {}
21impl FromStrProp for LightColor {}
22impl FromStrProp for Negated {}
23
24impl<T: FromStrProp> EntityProp<'_> for T
25where
26    EntityParseError: From<<T as FromStr>::Err>,
27{
28    fn parse(raw: &'_ str) -> Result<Self, EntityParseError> {
29        Ok(raw.parse()?)
30    }
31}
32
33impl<T: FromStrProp, const N: usize> EntityProp<'_> for [T; N]
34where
35    EntityParseError: From<<T as FromStr>::Err>,
36    [T; N]: Default,
37{
38    fn parse(raw: &'_ str) -> Result<Self, EntityParseError> {
39        let mut values = raw.split_whitespace().map(T::from_str);
40        let mut result = <[T; N]>::default();
41        for item in result.iter_mut() {
42            *item = values.next().ok_or(EntityParseError::ElementCount)??;
43        }
44        Ok(result)
45    }
46}
47
48impl<'a> EntityProp<'a> for &'a str {
49    fn parse(raw: &'a str) -> Result<Self, EntityParseError> {
50        Ok(raw)
51    }
52}
53
54impl EntityProp<'_> for bool {
55    fn parse(raw: &'_ str) -> Result<Self, EntityParseError> {
56        Ok(raw != "0" && raw != "no")
57    }
58}
59
60impl<'a, T: EntityProp<'a>> EntityProp<'a> for Option<T> {
61    fn parse(raw: &'a str) -> Result<Self, EntityParseError> {
62        Ok(Some(T::parse(raw)?))
63    }
64}
65
66#[derive(Debug, Error)]
67pub enum EntityParseError {
68    #[error("wrong number of elements")]
69    ElementCount,
70    #[error(transparent)]
71    Float(#[from] ParseFloatError),
72    #[error(transparent)]
73    Int(#[from] ParseIntError),
74}