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