microcad_lang/syntax/
attribute.rs1use crate::{src_ref::*, syntax::*};
7use derive_more::{Deref, DerefMut};
8
9#[derive(Clone)]
11pub enum AttributeCommand {
12 Call(Option<Identifier>, Option<ArgumentList>),
14 Expression(Expression),
16}
17
18impl std::fmt::Display for AttributeCommand {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match &self {
21 AttributeCommand::Call(id, argument_list) => {
22 write!(
23 f,
24 "{id}{argument_list}",
25 id = match id {
26 Some(id) => format!("{id}"),
27 None => String::new(),
28 },
29 argument_list = match argument_list {
30 Some(argument_list) => format!("({argument_list})"),
31 None => String::new(),
32 }
33 )
34 }
35 AttributeCommand::Expression(expression) => write!(f, "{expression}"),
36 }
37 }
38}
39
40impl std::fmt::Debug for AttributeCommand {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match &self {
43 AttributeCommand::Call(id, argument_list) => {
44 write!(
45 f,
46 "{id:?}{argument_list:?}",
47 id = match id {
48 Some(id) => format!("{id:?}"),
49 None => String::new(),
50 },
51 argument_list = match argument_list {
52 Some(argument_list) => format!("({argument_list:?})"),
53 None => String::new(),
54 }
55 )
56 }
57 AttributeCommand::Expression(expression) => write!(f, "{expression:?}"),
58 }
59 }
60}
61
62impl SrcReferrer for AttributeCommand {
63 fn src_ref(&self) -> SrcRef {
64 match &self {
65 AttributeCommand::Call(identifier, argument_list) => {
66 match (identifier, argument_list) {
67 (None, None) => unreachable!("Invalid AttributeCommand::Call"),
68 (None, Some(arguments)) => arguments.src_ref(),
69 (Some(identifier), None) => identifier.src_ref(),
70 (Some(identifier), Some(arguments)) => SrcRef::merge(identifier, arguments),
71 }
72 }
73 AttributeCommand::Expression(expression) => expression.src_ref(),
74 }
75 }
76}
77
78#[derive(Clone)]
80pub struct Attribute {
81 pub id: Identifier,
83 pub commands: Vec<AttributeCommand>,
85 pub is_inner: bool,
87 pub src_ref: SrcRef,
89}
90
91impl Attribute {
92 pub fn single_command(&self) -> Option<&AttributeCommand> {
94 match self.commands.len() {
95 1 => self.commands.first(),
96 _ => None,
97 }
98 }
99}
100
101impl TreeDisplay for Attribute {
102 fn tree_print(&self, f: &mut std::fmt::Formatter, depth: TreeState) -> std::fmt::Result {
103 writeln!(f, "{:depth$}Attribute: {self}", "")
104 }
105}
106
107impl std::fmt::Display for Attribute {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 match self.is_inner {
110 true => write!(f, "#![")?,
111 false => write!(f, "#[")?,
112 }
113 match self.commands.is_empty() {
114 true => write!(f, "{}", self.id)?,
115 false => write!(
116 f,
117 "{} = {}",
118 self.id,
119 self.commands
120 .iter()
121 .map(|command| command.to_string())
122 .collect::<Vec<_>>()
123 .join(", ")
124 )?,
125 }
126 writeln!(f, "]")
127 }
128}
129
130impl std::fmt::Debug for Attribute {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 write!(f, "{self}")
133 }
134}
135
136impl SrcReferrer for Attribute {
137 fn src_ref(&self) -> crate::src_ref::SrcRef {
138 self.src_ref.clone()
139 }
140}
141
142#[derive(Clone, Default, Deref, DerefMut)]
144pub struct AttributeList(Vec<Attribute>);
145
146impl std::fmt::Display for AttributeList {
147 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
148 self.0.iter().try_for_each(|attr| writeln!(f, "{attr}"))
149 }
150}
151
152impl std::fmt::Debug for AttributeList {
153 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
154 write!(f, "{self}")
155 }
156}
157
158impl SrcReferrer for AttributeList {
159 fn src_ref(&self) -> SrcRef {
160 if self.0.is_empty() {
161 SrcRef(None)
162 } else {
163 SrcRef::merge(
164 &self.0.first().expect("One element").src_ref(),
165 &self.0.last().expect("Second element").src_ref(),
166 )
167 }
168 }
169}