1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
use std::{fmt::Write, iter::IntoIterator};
use rnix::{
types::{self, TokenWrapper, TypedNode},
SyntaxNode,
};
fn ast_from_text<N: TypedNode>(text: &str) -> N {
let parse = rnix::parse(text);
let node = match parse.node().descendants().find_map(N::cast) {
Some(it) => it,
None => {
panic!(
"Failed to make ast node `{}` from text `{}`",
std::any::type_name::<N>(),
text
)
}
};
node
}
pub fn parenthesize(node: &SyntaxNode) -> types::Paren {
ast_from_text(&format!("({})", node))
}
pub fn quote(node: &SyntaxNode) -> types::Str {
ast_from_text(&format!("\"{}\"", node))
}
pub fn unary_not(node: &SyntaxNode) -> types::UnaryOp {
ast_from_text(&format!("!{}", node))
}
pub fn inherit_stmt<'a>(nodes: impl IntoIterator<Item = &'a types::Ident>) -> types::Inherit {
let inherited_idents = nodes
.into_iter()
.map(|i| i.as_str().to_owned())
.collect::<Vec<_>>()
.join(" ");
ast_from_text(&format!("{{ inherit {}; }}", inherited_idents))
}
pub fn inherit_from_stmt<'a>(
from: SyntaxNode,
nodes: impl IntoIterator<Item = &'a types::Ident>,
) -> types::Inherit {
let inherited_idents = nodes
.into_iter()
.map(|i| i.as_str().to_owned())
.collect::<Vec<_>>()
.join(" ");
ast_from_text(&format!("{{ inherit ({}) {}; }}", from, inherited_idents))
}
pub fn attrset(
inherits: impl IntoIterator<Item = types::Inherit>,
entries: impl IntoIterator<Item = types::KeyValue>,
recursive: bool,
) -> types::AttrSet {
let mut buffer = String::new();
writeln!(buffer, "{}{{", if recursive { "rec " } else { "" }).unwrap();
for inherit in inherits.into_iter() {
writeln!(buffer, " {}", inherit.node().text()).unwrap();
}
for entry in entries.into_iter() {
writeln!(buffer, " {}", entry.node().text()).unwrap();
}
write!(buffer, "}}").unwrap();
ast_from_text(&buffer)
}
pub fn select(set: &SyntaxNode, index: &SyntaxNode) -> types::Select {
ast_from_text(&format!("{}.{}", set, index))
}
pub fn ident(text: &str) -> types::Ident {
ast_from_text(text)
}
pub fn empty() -> types::Root {
ast_from_text("")
}
// TODO: make `op` strongly typed here
pub fn binary(lhs: &SyntaxNode, op: &str, rhs: &SyntaxNode) -> types::BinOp {
ast_from_text(&format!("{} {} {}", lhs, op, rhs))
}
pub fn or_default(set: &SyntaxNode, index: &SyntaxNode, default: &SyntaxNode) -> types::OrDefault {
ast_from_text(&format!("{}.{} or {}", set, index, default))
}
|