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}