1use crate::ast::keyword::Keyword;
2use crate::ast::expression::Expression;
3use crate::ast::identifier::Identifier;
4use crate::ast::span::Span;
5use crate::{declare_container_node, impl_container_node_defaults, node_optional_child_fn, node_child_fn};
6use crate::ast::literals::DictionaryLiteral;
7use crate::format::Writer;
8use crate::traits::has_availability::HasAvailability;
9use crate::traits::info_provider::InfoProvider;
10use crate::traits::named_identifiable::NamedIdentifiable;
11use crate::traits::node_trait::NodeTrait;
12use crate::traits::write::Write;
13
14declare_container_node!(Config, named, availability,
15    pub keyword: usize,
16    pub identifier: Option<usize>,
17    pub dictionary_literal: usize,
18    pub unattached_identifiers: Vec<Identifier>
19);
20
21impl_container_node_defaults!(Config, availability);
22
23impl Config {
24
25    node_child_fn!(keyword, Keyword);
26
27    node_optional_child_fn!(identifier, Identifier);
28
29    node_child_fn!(dictionary_literal, DictionaryLiteral);
30
31    pub fn name_span(&self) -> Span {
32        if let Some(identifier) = self.identifier() {
33            identifier.span()
34        } else {
35            self.keyword().span
36        }
37    }
38
39    pub fn get_item(&self, name: impl AsRef<str>) -> Option<&Expression> {
40        self.dictionary_literal().expressions().find(|item| item.key().named_key_without_resolving().is_some() && item.key().named_key_without_resolving().unwrap() == name.as_ref() && item.is_available()).map(|item| item.value())
41    }
42
43    pub fn items(&self) -> Vec<(&Expression, &Expression)> {
44        self.dictionary_literal().expressions().map(|e| (e.key(), e.value())).collect()
45    }
46}
47
48impl NamedIdentifiable for Config {
49
50    fn string_path(&self) -> &Vec<String> {
51        &self.string_path
52    }
53
54    fn name(&self) -> &str {
55        if let Some(identifier) = self.identifier() {
56            identifier.name()
57        } else {
58            self.keyword().name()
59        }
60    }
61}
62
63impl InfoProvider for Config {
64
65    fn namespace_skip(&self) -> usize {
66        1
67    }
68}
69
70impl Write for Config {
71    fn write<'a>(&'a self, writer: &mut Writer<'a>) {
72        writer.write_children(self, self.children.values());
73    }
74
75    fn is_block_level_element(&self) -> bool {
76        true
77    }
78}