1
use uniplate::uniplate::Uniplate;
2
use uniplate_derive::Uniplate;
3

            
4
#[derive(Clone, Debug, PartialEq, Eq, Uniplate)]
5
enum TestEnum {
6
    A(i32),
7
    B(Box<TestEnum>),
8
    C(Vec<TestEnum>),
9
    D(bool, Box<TestEnum>),
10
    E(Box<TestEnum>, Box<TestEnum>),
11
    F((Box<TestEnum>, Box<TestEnum>)),
12
    G((Box<TestEnum>, (Box<TestEnum>, i32))),
13
    H(Vec<Vec<TestEnum>>),
14
    I(Vec<TestEnum>, i32, Vec<TestEnum>),
15
}
16

            
17
#[test]
18
fn increase_number_of_children() {
19
    let c = TestEnum::C(vec![TestEnum::A(42)]);
20
    let context = c.uniplate().1;
21
    assert_eq!(
22
        context(vec![TestEnum::A(42), TestEnum::A(42)]),
23
        Err(uniplate::uniplate::UniplateError::WrongNumberOfChildren(
24
            1, 2
25
        ))
26
    );
27
}
28

            
29
#[test]
30
fn decrease_number_of_children() {
31
    let c = TestEnum::C(vec![TestEnum::A(42)]);
32
    let context = c.uniplate().1;
33
    assert_eq!(
34
        context(vec![]),
35
        Err(uniplate::uniplate::UniplateError::WrongNumberOfChildren(
36
            1, 0
37
        ))
38
    );
39
}
40

            
41
#[test]
42
fn derive_context_empty() {
43
    let a = TestEnum::A(42);
44
    let context = a.uniplate().1;
45
    assert_eq!(context(vec![]).unwrap(), a)
46
}
47

            
48
#[test]
49
fn derive_context_box() {
50
    let a = TestEnum::A(42);
51
    let b = TestEnum::B(Box::new(a.clone()));
52
    let context = b.uniplate().1;
53
    assert_eq!(context(vec![a.clone()]).unwrap(), b);
54
}
55

            
56
#[test]
57
fn derive_context_vec() {
58
    let a = TestEnum::A(1);
59
    let b = TestEnum::B(Box::new(TestEnum::A(2)));
60
    let c = TestEnum::C(vec![a.clone(), b.clone()]);
61
    let context = c.uniplate().1;
62
    assert_eq!(context(vec![a.clone(), b.clone()]).unwrap(), c);
63
}
64

            
65
#[test]
66
fn derive_context_two() {
67
    let d = TestEnum::D(true, Box::new(TestEnum::A(42)));
68
    let context = d.uniplate().1;
69
    assert_eq!(context(vec![TestEnum::A(42)]).unwrap(), d);
70
}
71

            
72
#[test]
73
fn derive_context_tuple() {
74
    let e = TestEnum::F((Box::new(TestEnum::A(1)), Box::new(TestEnum::A(2))));
75
    let context = e.uniplate().1;
76
    assert_eq!(context(vec![TestEnum::A(1), TestEnum::A(2)]).unwrap(), e);
77
}
78

            
79
#[test]
80
fn derive_context_different_variants() {
81
    let f = TestEnum::E(
82
        Box::new(TestEnum::A(1)),
83
        Box::new(TestEnum::B(Box::new(TestEnum::A(2)))),
84
    );
85
    let context = f.uniplate().1;
86
    assert_eq!(
87
        context(vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2)))]).unwrap(),
88
        f
89
    );
90
}
91

            
92
#[test]
93
fn derive_context_nested_tuples() {
94
    let g = TestEnum::G((Box::new(TestEnum::A(1)), (Box::new(TestEnum::A(2)), 42)));
95
    let context = g.uniplate().1;
96
    assert_eq!(context(vec![TestEnum::A(1), TestEnum::A(2)]).unwrap(), g);
97
}
98

            
99
#[test]
100
fn derive_context_nested_vectors() {
101
    let h = TestEnum::H(vec![
102
        vec![TestEnum::A(1), TestEnum::A(2)],
103
        vec![TestEnum::A(3), TestEnum::A(4)],
104
    ]);
105
    let context = h.uniplate().1;
106
    assert_eq!(
107
        context(vec![
108
            TestEnum::A(1),
109
            TestEnum::A(2),
110
            TestEnum::A(3),
111
            TestEnum::A(4)
112
        ])
113
        .unwrap(),
114
        h
115
    );
116
}
117

            
118
#[test]
119
fn derive_context_multiple_vecs() {
120
    let i = TestEnum::I(
121
        vec![TestEnum::A(1), TestEnum::A(2)],
122
        42,
123
        vec![TestEnum::A(3), TestEnum::A(4)],
124
    );
125
    let context = i.uniplate().1;
126
    assert_eq!(
127
        context(vec![
128
            TestEnum::A(1),
129
            TestEnum::A(2),
130
            TestEnum::A(3),
131
            TestEnum::A(4)
132
        ])
133
        .unwrap(),
134
        i
135
    );
136
}
137

            
138
#[test]
139
fn box_change_child() {
140
    let b = TestEnum::B(Box::new(TestEnum::A(1)));
141
    let context = b.uniplate().1;
142
    assert_eq!(
143
        context(vec![TestEnum::C(vec![TestEnum::A(41), TestEnum::A(42)])]).unwrap(),
144
        TestEnum::B(Box::new(TestEnum::C(vec![
145
            TestEnum::A(41),
146
            TestEnum::A(42)
147
        ])))
148
    );
149
}
150

            
151
#[test]
152
fn derive_children_empty() {
153
    let a = TestEnum::A(42);
154
    let children = a.uniplate().0;
155
    assert_eq!(children, vec![]);
156
}
157

            
158
#[test]
159
fn derive_children_box() {
160
    let b = TestEnum::B(Box::new(TestEnum::A(42)));
161
    let children = b.uniplate().0;
162
    assert_eq!(children, vec![TestEnum::A(42)]);
163
}
164

            
165
#[test]
166
fn derive_children_vec() {
167
    let c = TestEnum::C(vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2)))]);
168
    let children = c.uniplate().0;
169
    assert_eq!(
170
        children,
171
        vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2))),]
172
    );
173
}
174

            
175
#[test]
176
fn derive_children_two() {
177
    let d = TestEnum::D(true, Box::new(TestEnum::A(42)));
178
    let children = d.uniplate().0;
179
    assert_eq!(children, vec![TestEnum::A(42)]);
180
}
181

            
182
#[test]
183
fn derive_children_tuple() {
184
    let e = TestEnum::F((Box::new(TestEnum::A(1)), Box::new(TestEnum::A(2))));
185
    let children = e.uniplate().0;
186
    assert_eq!(children, vec![TestEnum::A(1), TestEnum::A(2),]);
187
}
188

            
189
#[test]
190
fn derive_children_different_variants() {
191
    let f = TestEnum::E(
192
        Box::new(TestEnum::A(1)),
193
        Box::new(TestEnum::B(Box::new(TestEnum::A(2)))),
194
    );
195
    let children = f.uniplate().0;
196
    assert_eq!(
197
        children,
198
        vec![TestEnum::A(1), TestEnum::B(Box::new(TestEnum::A(2)))]
199
    );
200
}
201

            
202
#[test]
203
fn derive_children_nested_tuples() {
204
    let g = TestEnum::G((Box::new(TestEnum::A(1)), (Box::new(TestEnum::A(2)), 42)));
205
    let children = g.uniplate().0;
206
    assert_eq!(children, vec![TestEnum::A(1), TestEnum::A(2)])
207
}
208

            
209
#[test]
210
fn derive_children_nested_vectors() {
211
    let h = TestEnum::H(vec![
212
        vec![TestEnum::A(1), TestEnum::A(2)],
213
        vec![TestEnum::A(3), TestEnum::A(4)],
214
    ]);
215
    let children = h.uniplate().0;
216
    assert_eq!(
217
        children,
218
        vec![
219
            TestEnum::A(1),
220
            TestEnum::A(2),
221
            TestEnum::A(3),
222
            TestEnum::A(4)
223
        ]
224
    )
225
}
226

            
227
#[test]
228
fn derive_children_multiple_vecs() {
229
    let i = TestEnum::I(
230
        vec![TestEnum::A(1), TestEnum::A(2)],
231
        42,
232
        vec![TestEnum::A(3), TestEnum::A(4)],
233
    );
234
    let children = i.uniplate().0;
235
    assert_eq!(
236
        children,
237
        vec![
238
            TestEnum::A(1),
239
            TestEnum::A(2),
240
            TestEnum::A(3),
241
            TestEnum::A(4)
242
        ]
243
    );
244
}