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
95
96
97
98
99
100
101
102
103
104
105
106
use std::iter::IntoIterator;
use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::ptr::P;
use expr::ExprBuilder;
use invoke::{Invoke, Identity};
use stmt::StmtBuilder;
pub struct BlockBuilder<F=Identity> {
callback: F,
span: Span,
stmts: Vec<P<ast::Stmt>>,
block_check_mode: ast::BlockCheckMode,
}
impl BlockBuilder {
pub fn new() -> Self {
BlockBuilder::new_with_callback(Identity)
}
}
impl<F> BlockBuilder<F>
where F: Invoke<P<ast::Block>>,
{
pub fn new_with_callback(callback: F) -> Self {
BlockBuilder {
callback: callback,
span: DUMMY_SP,
stmts: Vec::new(),
block_check_mode: ast::BlockCheckMode::DefaultBlock,
}
}
pub fn span(mut self, span: Span) -> Self {
self.span = span;
self
}
pub fn unsafe_(mut self) -> Self {
let source = ast::UnsafeSource::CompilerGenerated;
self.block_check_mode = ast::BlockCheckMode::UnsafeBlock(source);
self
}
pub fn with_stmts<I>(mut self, iter: I) -> Self
where I: IntoIterator<Item=P<ast::Stmt>>
{
self.stmts.extend(iter);
self
}
pub fn with_stmt(mut self, stmt: P<ast::Stmt>) -> Self {
self.stmts.push(stmt);
self
}
pub fn stmt(self) -> StmtBuilder<Self> {
StmtBuilder::new_with_callback(self)
}
pub fn build_expr(self, expr: P<ast::Expr>) -> F::Result {
self.build_(Some(expr))
}
pub fn expr(self) -> ExprBuilder<Self> {
ExprBuilder::new_with_callback(self)
}
pub fn build(self) -> F::Result {
self.build_(None)
}
fn build_(self, expr: Option<P<ast::Expr>>) -> F::Result {
self.callback.invoke(P(ast::Block {
stmts: self.stmts,
expr: expr,
id: ast::DUMMY_NODE_ID,
rules: self.block_check_mode,
span: self.span,
}))
}
}
impl<F> Invoke<P<ast::Stmt>> for BlockBuilder<F>
where F: Invoke<P<ast::Block>>,
{
type Result = Self;
fn invoke(self, stmt: P<ast::Stmt>) -> Self {
self.with_stmt(stmt)
}
}
impl<F> Invoke<P<ast::Expr>> for BlockBuilder<F>
where F: Invoke<P<ast::Block>>,
{
type Result = F::Result;
fn invoke(self, expr: P<ast::Expr>) -> F::Result {
self.build_expr(expr)
}
}