color_span/view/
der.rs

1use std::fmt::Formatter;
2
3use internship::IStr;
4use serde::{
5    de::{IgnoredAny, MapAccess, Visitor},
6    Deserialize, Deserializer,
7};
8
9use code_span::CodeView;
10
11use crate::ColorView;
12
13struct ColorViewMap {}
14
15impl<'de> Deserialize<'de> for ColorView {
16    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
17    where
18        D: Deserializer<'de>,
19    {
20        deserializer.deserialize_map(ColorViewMap {})
21    }
22}
23
24impl<'de> Visitor<'de> for ColorViewMap {
25    type Value = ColorView;
26
27    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
28        formatter.write_str("Expect `ColorView` object")
29    }
30
31    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
32    where
33        A: MapAccess<'de>,
34    {
35        let mut text = String::new();
36        let mut colors = vec![];
37        let mut bits = vec![];
38
39        while let Some(key) = map.next_key::<&str>()? {
40            match key {
41                "text" => text = map.next_value()?,
42                "colors" => colors = map.next_value::<Vec<String>>()?,
43                "bits" => bits = map.next_value::<Vec<u8>>()?,
44                _ => {
45                    map.next_value::<IgnoredAny>()?;
46                }
47            }
48        }
49        let mut info = Vec::with_capacity(bits.len());
50        for bit in bits {
51            let item = match colors.get(bit as usize).map(|s| s.as_str()) {
52                None | Some("") => None,
53                Some(s) => Some(IStr::new(s)),
54            };
55            info.push(item);
56        }
57
58        Ok(ColorView { span: CodeView::new(text, info) })
59    }
60}