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