logix_type/types/
map.rs

1use indexmap::IndexMap;
2use logix_vfs::LogixVfs;
3
4use crate::{
5    error::{Result, Warn},
6    parser::LogixParser,
7    token::{Brace, Token},
8    type_trait::{LogixTypeDescriptor, LogixValueDescriptor, Value},
9    types::ShortStr,
10    LogixType,
11};
12
13pub type Map<V, K = ShortStr> = IndexMap<K, V>;
14
15impl<T: LogixType, K> LogixType for Map<T, K>
16where
17    K: AsRef<str>,
18    K: From<ShortStr>,
19    K: std::hash::Hash,
20    K: Eq,
21{
22    fn descriptor() -> &'static LogixTypeDescriptor {
23        static RET: LogixTypeDescriptor = LogixTypeDescriptor {
24            name: "string",
25            doc: "a valid utf-8 string",
26            value: LogixValueDescriptor::Native,
27        };
28        &RET
29    }
30
31    fn default_value() -> Option<Self> {
32        Some(Self::new())
33    }
34
35    fn logix_parse<FS: LogixVfs>(p: &mut LogixParser<FS>) -> Result<Value<Self>> {
36        let mut map = IndexMap::new();
37
38        let start = p.req_token(
39            "map",
40            Token::Brace {
41                start: true,
42                brace: Brace::Curly,
43            },
44        )?;
45        p.req_token("map", Token::Newline(false))?;
46
47        while let Some((key, value)) = p.read_key_value("map", Brace::Curly)? {
48            if let (i, Some(_)) = map.insert_full(K::from(key.value), value.value) {
49                p.warning(Warn::DuplicateMapEntry {
50                    span: key.span,
51                    key: map.get_index(i).unwrap().0.as_ref().into(),
52                })?;
53            }
54        }
55
56        Ok(Value {
57            value: map,
58            span: start,
59        })
60    }
61}