1use source_map_node::Node;
7
8#[derive(Debug, Clone, Default)]
9pub struct Attributes(pub Vec<Attribute>);
10
11impl Attributes {
12 #[must_use]
13 pub fn get_attributes(&self, name: &str) -> Self {
14 let vec: Vec<_> = self
15 .0
16 .iter()
17 .filter(|attr| attr.path.name == name)
18 .cloned()
19 .collect();
20
21 Self(vec)
22 }
23
24 #[must_use]
25 pub const fn is_empty(&self) -> bool {
26 self.0.is_empty()
27 }
28
29 #[must_use]
30 pub fn has_attribute(&self, name: &str) -> bool {
31 self.0.iter().any(|attr| attr.path.name == name)
32 }
33
34 #[must_use]
35 pub fn get_attribute(&self, name: &str) -> Option<&Attribute> {
36 self.0.iter().find(|attr| attr.path.name == name)
37 }
38
39 #[must_use]
40 pub fn get_fn_arg_by_name(&self, attr_name: &str, arg_fn_name: &str) -> Option<&AttributeArg> {
41 self.get_attribute(attr_name).and_then(|attr| {
42 attr.args.iter().find(|arg| {
43 if let AttributeArg::Function(id, _) = arg {
44 id.name == arg_fn_name
45 } else {
46 false
47 }
48 })
49 })
50 }
51
52 #[must_use]
53 pub fn get_fn_arg_sub_args(
54 &self,
55 attr_name: &str,
56 arg_fn_name: &str,
57 ) -> Option<&Vec<AttributeArg>> {
58 self.get_fn_arg_by_name(attr_name, arg_fn_name)
59 .and_then(|arg| {
60 if let AttributeArg::Function(_, sub_args) = arg {
61 Some(sub_args)
62 } else {
63 None }
65 })
66 }
67
68 #[must_use]
69 pub fn get_arg(&self, name: &str, arg_index: usize) -> Option<AttributeArg> {
70 self.get_args(name)
71 .and_then(|a| Option::from(a[arg_index].clone()))
72 }
73
74 #[must_use]
75 pub fn get_value(&self, name: &str, arg_index: usize) -> Option<AttributeValue> {
76 self.get_arg(name, arg_index).and_then(|arg| match arg {
77 AttributeArg::Literal(x) => Some(x),
78 _ => None,
79 })
80 }
81
82 #[must_use]
83 pub fn get_int(&self, name: &str, arg_index: usize) -> Option<i32> {
84 self.get_value(name, arg_index).and_then(|x| match x {
85 AttributeValue::Int(v) => Some(v),
86 _ => None,
87 })
88 }
89 #[must_use]
90 pub fn get_int_from_fn_arg(
91 &self,
92 attr_name: &str,
93 arg_fn_name: &str,
94 sub_arg_index: usize,
95 ) -> Option<i32> {
96 self.get_fn_arg_sub_args(attr_name, arg_fn_name)
97 .and_then(|sub_args| {
98 sub_args
99 .get(sub_arg_index)
100 .and_then(|sub_arg| match sub_arg {
101 AttributeArg::Literal(attr_value) => match attr_value {
102 AttributeValue::Int(v) => Some(*v),
103 _ => None,
104 },
105 _ => None,
106 })
107 })
108 }
109
110 #[must_use]
111 pub fn get_string_from_fn_arg(
112 &self,
113 attr_name: &str,
114 arg_fn_name: &str,
115 sub_arg_index: usize,
116 ) -> Option<&String> {
117 self.get_fn_arg_sub_args(attr_name, arg_fn_name)
118 .and_then(|sub_args| {
119 sub_args
120 .get(sub_arg_index)
121 .and_then(|sub_arg| match sub_arg {
122 AttributeArg::Literal(attr_value) => match attr_value {
123 AttributeValue::String(s) => Some(s),
124 _ => None,
125 },
126 _ => None,
127 })
128 })
129 }
130
131 #[must_use]
132 pub fn get_string(&self, name: &str, arg_index: usize) -> Option<String> {
133 self.get_value(name, arg_index).and_then(|x| match x {
134 AttributeValue::String(v) => Some(v),
135 _ => None,
136 })
137 }
138 #[must_use]
139 pub fn get_args(&self, name: &str) -> Option<Vec<AttributeArg>> {
140 self.get_attribute(name)
141 .and_then(|a| Option::from(a.args.clone()))
142 }
143}
144
145#[derive(Debug, Clone)]
146pub struct Attribute {
147 pub path: AttributeIdentifier,
148 pub args: Vec<AttributeArg>,
149 pub node: Node,
150}
151
152#[derive(Debug, Clone)]
153pub struct AttributeIdentifier {
154 pub name: String,
155}
156
157#[derive(Debug, Clone)]
158pub enum AttributeArg {
159 Path(AttributeIdentifier), Literal(AttributeValue), Function(AttributeIdentifier, Vec<AttributeArg>), }
163
164#[derive(Debug, Clone)]
165pub enum AttributeValue {
166 String(String),
167 Int(i32),
168 Bool(bool),
169}