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}