vbsp_common/
color.rs

1use crate::{EntityParseError, EntityProp};
2use serde::de::{Error, Unexpected};
3use serde::{Deserialize, Deserializer};
4use std::str::FromStr;
5
6#[derive(Debug, Clone)]
7pub struct Color {
8    pub r: u8,
9    pub g: u8,
10    pub b: u8,
11}
12
13impl FromStr for Color {
14    type Err = EntityParseError;
15
16    fn from_str(s: &str) -> Result<Self, Self::Err> {
17        let mut floats = s.split_whitespace().map(u8::from_str);
18        let r = floats.next().ok_or(EntityParseError::ElementCount)??;
19        let g = floats.next().ok_or(EntityParseError::ElementCount)??;
20        let b = floats.next().ok_or(EntityParseError::ElementCount)??;
21        if floats.next().is_some() {
22            return Err(EntityParseError::ElementCount);
23        }
24        Ok(Self { r, g, b })
25    }
26}
27
28impl<'de> Deserialize<'de> for Color {
29    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30    where
31        D: Deserializer<'de>,
32    {
33        let str = <&str>::deserialize(deserializer)?;
34        let [r, g, b] = <[u8; 3]>::parse(str)
35            .map_err(|_| D::Error::invalid_value(Unexpected::Other(str), &"a list of 3 numbers"))?;
36        Ok(Color { r, g, b })
37    }
38}