shadowplay/puppet_pp_printer/
resource.rs1use crate::puppet_pp_printer::Printer;
2use pretty::RcDoc;
3
4impl<EXTRA> Printer for crate::puppet_lang::resource_collection::SearchExpression<EXTRA> {
5 fn to_doc(&self) -> RcDoc<()> {
6 match &self.value {
7 crate::puppet_lang::resource_collection::ExpressionVariant::Equal((left, right)) => {
8 crate::puppet_pp_printer::expression::infix_to_doc(
9 RcDoc::text(&left.name),
10 crate::puppet_pp_printer::term::to_doc(right, false),
11 "==",
12 )
13 }
14 crate::puppet_lang::resource_collection::ExpressionVariant::NotEqual((left, right)) => {
15 crate::puppet_pp_printer::expression::infix_to_doc(
16 RcDoc::text(&left.name),
17 crate::puppet_pp_printer::term::to_doc(right, false),
18 "!=",
19 )
20 }
21 crate::puppet_lang::resource_collection::ExpressionVariant::And((left, right)) => {
22 crate::puppet_pp_printer::expression::infix_to_doc(
23 left.to_doc(),
24 right.to_doc(),
25 "and",
26 )
27 }
28 crate::puppet_lang::resource_collection::ExpressionVariant::Or((left, right)) => {
29 crate::puppet_pp_printer::expression::infix_to_doc(
30 left.to_doc(),
31 right.to_doc(),
32 "or",
33 )
34 }
35 crate::puppet_lang::resource_collection::ExpressionVariant::Parens(v) => {
36 RcDoc::text("(")
37 .append(v.to_doc().nest(2))
38 .append(RcDoc::text(")"))
39 .group()
40 }
41 }
42 }
43}
44
45impl<EXTRA> Printer for crate::puppet_lang::resource_collection::ResourceCollection<EXTRA> {
46 fn to_doc(&self) -> RcDoc<()> {
47 let search_expression = match &self.search_expression {
48 Some(v) => RcDoc::softline()
49 .append(RcDoc::text("<|"))
50 .append(RcDoc::softline())
51 .append(v.to_doc())
52 .nest(2)
53 .append(RcDoc::softline())
54 .append(RcDoc::text("|>")),
55 None => RcDoc::nil(),
56 };
57
58 crate::puppet_pp_printer::comment::comment_or(
59 &self.comment,
60 RcDoc::hardline(),
61 RcDoc::nil(),
62 )
63 .append(self.type_specification.to_doc())
64 .append(search_expression)
65 }
66}
67
68impl<EXTRA> Printer for crate::puppet_lang::statement::ResourceAttribute<EXTRA> {
69 fn to_doc(&self) -> RcDoc<()> {
70 let value = match &self.value {
71 crate::puppet_lang::statement::ResourceAttributeVariant::Name((k, v)) => {
72 RcDoc::text(&k.data)
73 .append(RcDoc::column(|w| {
74 let offset = (w / crate::puppet_pp_printer::ARROW_STEP + 1)
75 * crate::puppet_pp_printer::ARROW_STEP;
76 RcDoc::text(format!("{}=>", " ".repeat(offset - w)))
77 }))
78 .append(RcDoc::softline())
79 .append(crate::puppet_pp_printer::expression::to_doc(v, false))
80 .group()
81 .nest(2)
82 }
83 crate::puppet_lang::statement::ResourceAttributeVariant::Group(v) => RcDoc::text("*")
84 .append(RcDoc::softline())
85 .append(RcDoc::column(|w| {
86 let offset = (w / crate::puppet_pp_printer::ARROW_STEP + 1)
87 * crate::puppet_pp_printer::ARROW_STEP;
88 RcDoc::text(format!("{}=>", " ".repeat(offset - w)))
89 }))
90 .append(RcDoc::softline())
91 .append(crate::puppet_pp_printer::term::to_doc(v, false))
92 .group()
93 .nest(2),
94 };
95
96 crate::puppet_pp_printer::comment::comment_or(
97 &self.comment,
98 RcDoc::hardline(),
99 RcDoc::nil(),
100 )
101 .append(value)
102 }
103}
104
105impl<EXTRA> Printer for crate::puppet_lang::statement::Resource<EXTRA> {
106 fn to_doc(&self) -> RcDoc<()> {
107 let inner = if self.attributes.value.is_empty() {
108 RcDoc::nil()
109 } else {
110 RcDoc::hardline().append(RcDoc::intersperse(
111 self.attributes.value.iter().map(|elt| elt.to_doc()),
112 RcDoc::text(",").append(RcDoc::hardline()),
113 ))
114 };
115
116 let inner = inner.append(crate::puppet_pp_printer::comment::to_doc(
117 &self.attributes.last_comment,
118 ));
119
120 crate::puppet_pp_printer::expression::to_doc(&self.title, false)
121 .append(RcDoc::text(":"))
122 .append(inner)
123 .nest(2)
124 }
125}
126
127impl<EXTRA> Printer for crate::puppet_lang::statement::ResourceSet<EXTRA> {
128 fn to_doc(&self) -> RcDoc<()> {
129 let is_virtual = if self.is_virtual {
130 RcDoc::text("@")
131 } else {
132 RcDoc::nil()
133 };
134
135 if self.list.value.len() == 1
137 && self.list.value.first().unwrap().attributes.value.is_empty()
138 && self
139 .list
140 .value
141 .first()
142 .unwrap()
143 .attributes
144 .last_comment
145 .is_empty()
146 {
147 return crate::puppet_pp_printer::comment::comment_or(
148 &self.comment,
149 RcDoc::hardline(),
150 RcDoc::nil(),
151 )
152 .append(is_virtual)
153 .append(self.name.to_doc())
154 .append(RcDoc::softline())
155 .append(RcDoc::text("{"))
156 .append(RcDoc::softline())
157 .append(RcDoc::intersperse(
158 self.list.value.iter().map(|elt| elt.to_doc()),
159 RcDoc::nil(),
160 ))
161 .nest(2)
162 .append(RcDoc::softline())
163 .append(RcDoc::text("}"));
164 }
165
166 let inner = RcDoc::intersperse(
167 self.list.value.iter().map(|elt| elt.to_doc()),
168 RcDoc::text(";").append(RcDoc::hardline()),
169 )
170 .append(crate::puppet_pp_printer::comment::to_doc(
171 &self.list.last_comment,
172 ));
173
174 crate::puppet_pp_printer::comment::comment_or(
175 &self.comment,
176 RcDoc::hardline(),
177 RcDoc::nil(),
178 )
179 .append(is_virtual)
180 .append(self.name.to_doc())
181 .append(RcDoc::softline())
182 .append(RcDoc::text("{"))
183 .append(RcDoc::softline())
184 .append(inner)
185 .nest(2)
186 .append(RcDoc::hardline())
187 .append(RcDoc::text("}"))
188 }
189}
190
191impl<EXTRA> Printer for crate::puppet_lang::statement::RelationEltVariant<EXTRA> {
192 fn to_doc(&self) -> RcDoc<()> {
193 match self {
194 crate::puppet_lang::statement::RelationEltVariant::ResourceSet(v) => v.to_doc(),
195 crate::puppet_lang::statement::RelationEltVariant::ResourceCollection(v) => v.to_doc(),
196 }
197 }
198}
199
200impl<EXTRA> Printer for crate::puppet_lang::statement::RelationElt<EXTRA> {
201 fn to_doc(&self) -> RcDoc<()> {
202 if self.data.value.len() == 1 && self.data.last_comment.is_empty() {
203 return self.data.value.first().unwrap().to_doc();
204 }
205
206 let inner = RcDoc::intersperse(
207 self.data
208 .value
209 .iter()
210 .map(|x| x.to_doc().append(RcDoc::text(","))),
211 RcDoc::softline(),
212 )
213 .group()
214 .append(crate::puppet_pp_printer::comment::to_doc(
215 &self.data.last_comment,
216 ));
217
218 RcDoc::text("[")
219 .append(RcDoc::softline())
220 .append(inner)
221 .nest(2)
222 .append(RcDoc::softline())
223 .append(RcDoc::text("]"))
224 }
225}
226
227impl<EXTRA> Printer for crate::puppet_lang::statement::RelationType<EXTRA> {
228 fn to_doc(&self) -> RcDoc<()> {
229 match self.variant {
230 crate::puppet_lang::statement::RelationVariant::ExecOrderRight => RcDoc::text("->"),
231 crate::puppet_lang::statement::RelationVariant::NotifyRight => RcDoc::text("~>"),
232 crate::puppet_lang::statement::RelationVariant::ExecOrderLeft => RcDoc::text("<-"),
233 crate::puppet_lang::statement::RelationVariant::NotifyLeft => RcDoc::text("<~"),
234 }
235 }
236}
237
238impl<EXTRA> Printer for crate::puppet_lang::statement::Relation<EXTRA> {
239 fn to_doc(&self) -> RcDoc<()> {
240 crate::puppet_pp_printer::comment::comment_or(
241 &self.comment,
242 RcDoc::hardline(),
243 RcDoc::nil(),
244 )
245 .append(self.relation_type.to_doc())
246 .append(RcDoc::space())
247 .append(self.relation_to.to_doc())
248 }
249}
250
251impl<EXTRA> Printer for crate::puppet_lang::statement::RelationList<EXTRA> {
252 fn to_doc(&self) -> RcDoc<()> {
253 let head = self.head.to_doc();
254 match &self.tail {
255 None => head,
256 Some(v) => head.append(RcDoc::softline()).append(v.to_doc()),
257 }
258 }
259}
260
261#[test]
262fn test_idempotence_short() {
263 let cases = vec![
264 "Class[ a ] -> Class[ b::c ]",
265 "[ Class[ a ], Class[ b ], ] -> Class[ b::c ]",
266 "Class[ a ] -> ClassB <| (abc != 1) and c == test or (c == notest and abc == 1) |>",
267 "file { '/etc/passwd':\n ensure => file,\n mode => '0644'\n}",
268 "file { '/etc/passwd':\n ensure => file,\n mode => '0644';\n '/etc/group':\n ensure => file\n}",
269 "file { '/etc/passwd':\n unless => true\n}",
271 ];
272
273 for case in cases {
274 let (_, v) = crate::puppet_parser::statement::parse_statement_list(
275 crate::puppet_parser::Span::new(case),
276 )
277 .unwrap();
278
279 let mut w = Vec::new();
280 crate::puppet_pp_printer::statement::statement_block_to_doc(&v, false)
281 .render(100, &mut w)
282 .unwrap();
283 let generated = String::from_utf8(w).unwrap();
284 println!("{} ==>\n------\n{}\n------", case, generated);
285
286 assert_eq!(&generated, case)
287 }
288}