@@ -9,6 +9,8 @@ use router::Router;
9
9
use serde:: Serialize ;
10
10
use std:: collections:: { HashMap , VecDeque } ;
11
11
12
+ const DEFAULT_NAME : & str = "default" ;
13
+
12
14
#[ derive( Debug , Clone , PartialEq , Eq , Serialize ) ]
13
15
struct FeaturesPage {
14
16
metadata : MetaData ,
@@ -38,28 +40,14 @@ pub fn build_features_handler(req: &mut Request) -> IronResult<Response> {
38
40
39
41
let row = cexpect ! ( req, rows. get( 0 ) ) ;
40
42
43
+ let mut features = None ;
41
44
let mut default_len = 0 ;
42
- let features = row
43
- . get :: < ' _ , usize , Option < Vec < Feature > > > ( 0 )
44
- . map ( |raw| {
45
- raw. into_iter ( )
46
- . filter ( |feature| !feature. is_private ( ) )
47
- . map ( |feature| ( feature. name . clone ( ) , feature) )
48
- . collect :: < HashMap < String , Feature > > ( )
49
- } )
50
- . map ( |mut feature_map| {
51
- let mut features = get_tree_structure_from_default ( & mut feature_map) ;
52
- let mut remaining = feature_map
53
- . into_iter ( )
54
- . map ( |( _, feature) | feature)
55
- . collect :: < Vec < Feature > > ( ) ;
56
- remaining. sort_by_key ( |feature| feature. subfeatures . len ( ) ) ;
57
-
58
- default_len = features. len ( ) ;
59
-
60
- features. extend ( remaining. into_iter ( ) . rev ( ) ) ;
61
- features
62
- } ) ;
45
+
46
+ if let Some ( raw) = row. get ( 0 ) {
47
+ let result = order_features_and_count_default_len ( raw) ;
48
+ features = Some ( result. 0 ) ;
49
+ default_len = result. 1 ;
50
+ }
63
51
64
52
FeaturesPage {
65
53
metadata : cexpect ! ( req, MetaData :: from_crate( & mut conn, & name, & version) ) ,
@@ -69,11 +57,26 @@ pub fn build_features_handler(req: &mut Request) -> IronResult<Response> {
69
57
. into_response ( req)
70
58
}
71
59
60
+ fn order_features_and_count_default_len ( raw : Vec < Feature > ) -> ( Vec < Feature > , usize ) {
61
+ let mut feature_map = get_feature_map ( raw) ;
62
+ let mut features = get_tree_structure_from_default ( & mut feature_map) ;
63
+ let mut remaining: Vec < _ > = feature_map
64
+ . into_iter ( )
65
+ . map ( |( _, feature) | feature)
66
+ . collect ( ) ;
67
+ remaining. sort_by_key ( |feature| feature. subfeatures . len ( ) ) ;
68
+
69
+ let default_len = features. len ( ) ;
70
+
71
+ features. extend ( remaining. into_iter ( ) . rev ( ) ) ;
72
+ ( features, default_len)
73
+ }
74
+
72
75
fn get_tree_structure_from_default ( feature_map : & mut HashMap < String , Feature > ) -> Vec < Feature > {
73
76
let mut features = Vec :: new ( ) ;
74
77
let mut queue: VecDeque < String > = VecDeque :: new ( ) ;
75
78
76
- queue. push_back ( "default" . into ( ) ) ;
79
+ queue. push_back ( DEFAULT_NAME . into ( ) ) ;
77
80
while !queue. is_empty ( ) {
78
81
let name = queue. pop_front ( ) . unwrap ( ) ;
79
82
if let Some ( feature) = feature_map. remove ( & name) {
@@ -86,3 +89,132 @@ fn get_tree_structure_from_default(feature_map: &mut HashMap<String, Feature>) -
86
89
}
87
90
features
88
91
}
92
+
93
+ fn get_feature_map ( raw : Vec < Feature > ) -> HashMap < String , Feature > {
94
+ raw. into_iter ( )
95
+ . filter ( |feature| !feature. is_private ( ) )
96
+ . map ( |feature| ( feature. name . clone ( ) , feature) )
97
+ . collect ( )
98
+ }
99
+
100
+ #[ cfg( test) ]
101
+ mod tests {
102
+ use crate :: db:: types:: Feature ;
103
+ use crate :: web:: features:: {
104
+ get_feature_map, get_tree_structure_from_default, order_features_and_count_default_len,
105
+ DEFAULT_NAME ,
106
+ } ;
107
+
108
+ #[ test]
109
+ fn test_feature_map_filters_private ( ) {
110
+ let private1 = Feature :: new ( "_private1" . into ( ) , vec ! [ "feature1" . into( ) ] ) ;
111
+ let feature2 = Feature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
112
+
113
+ let raw = vec ! [ private1. clone( ) , feature2. clone( ) ] ;
114
+ let feature_map = get_feature_map ( raw) ;
115
+
116
+ assert_eq ! ( feature_map. len( ) , 1 ) ;
117
+ assert ! ( feature_map. contains_key( & feature2. name) ) ;
118
+ assert ! ( !feature_map. contains_key( & private1. name) ) ;
119
+ }
120
+
121
+ #[ test]
122
+ fn test_default_tree_structure_with_nested_default ( ) {
123
+ let default = Feature :: new ( DEFAULT_NAME . into ( ) , vec ! [ "feature1" . into( ) ] ) ;
124
+ let non_default = Feature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
125
+ let feature1 = Feature :: new (
126
+ "feature1" . into ( ) ,
127
+ vec ! [ "feature2" . into( ) , "feature3" . into( ) ] ,
128
+ ) ;
129
+ let feature2 = Feature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
130
+ let feature3 = Feature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
131
+
132
+ let raw = vec ! [
133
+ default . clone( ) ,
134
+ non_default. clone( ) ,
135
+ feature3. clone( ) ,
136
+ feature2. clone( ) ,
137
+ feature1. clone( ) ,
138
+ ] ;
139
+ let mut feature_map = get_feature_map ( raw) ;
140
+ let default_tree = get_tree_structure_from_default ( & mut feature_map) ;
141
+
142
+ assert_eq ! ( feature_map. len( ) , 1 ) ;
143
+ assert_eq ! ( default_tree. len( ) , 4 ) ;
144
+ assert ! ( feature_map. contains_key( & non_default. name) ) ;
145
+ assert ! ( !feature_map. contains_key( & default . name) ) ;
146
+ assert_eq ! ( default_tree. get( 0 ) , Some ( & default ) ) ;
147
+ assert_eq ! ( default_tree. get( 1 ) , Some ( & feature1) ) ;
148
+ assert_eq ! ( default_tree. get( 2 ) , Some ( & feature2) ) ;
149
+ assert_eq ! ( default_tree. get( 3 ) , Some ( & feature3) ) ;
150
+ }
151
+
152
+ #[ test]
153
+ fn test_default_tree_structure_without_default ( ) {
154
+ let feature1 = Feature :: new (
155
+ "feature1" . into ( ) ,
156
+ vec ! [ "feature2" . into( ) , "feature3" . into( ) ] ,
157
+ ) ;
158
+ let feature2 = Feature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
159
+ let feature3 = Feature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
160
+
161
+ let raw = vec ! [ feature3. clone( ) , feature2. clone( ) , feature1. clone( ) ] ;
162
+ let mut feature_map = get_feature_map ( raw) ;
163
+ let default_tree = get_tree_structure_from_default ( & mut feature_map) ;
164
+
165
+ assert_eq ! ( feature_map. len( ) , 3 ) ;
166
+ assert_eq ! ( default_tree. len( ) , 0 ) ;
167
+ assert ! ( feature_map. contains_key( & feature1. name) ) ;
168
+ assert ! ( feature_map. contains_key( & feature2. name) ) ;
169
+ assert ! ( feature_map. contains_key( & feature3. name) ) ;
170
+ }
171
+
172
+ #[ test]
173
+ fn test_default_tree_structure_single_default ( ) {
174
+ let default = Feature :: new ( DEFAULT_NAME . into ( ) , Vec :: new ( ) ) ;
175
+ let non_default = Feature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
176
+
177
+ let raw = vec ! [ default . clone( ) , non_default. clone( ) ] ;
178
+ let mut feature_map = get_feature_map ( raw) ;
179
+ let default_tree = get_tree_structure_from_default ( & mut feature_map) ;
180
+
181
+ assert_eq ! ( feature_map. len( ) , 1 ) ;
182
+ assert_eq ! ( default_tree. len( ) , 1 ) ;
183
+ assert ! ( feature_map. contains_key( & non_default. name) ) ;
184
+ assert ! ( !feature_map. contains_key( & default . name) ) ;
185
+ assert_eq ! ( default_tree. get( 0 ) , Some ( & default ) ) ;
186
+ }
187
+
188
+ #[ test]
189
+ fn test_order_features_and_get_len_without_default ( ) {
190
+ let feature1 = Feature :: new (
191
+ "feature1" . into ( ) ,
192
+ vec ! [ "feature10" . into( ) , "feature11" . into( ) ] ,
193
+ ) ;
194
+ let feature2 = Feature :: new ( "feature2" . into ( ) , vec ! [ "feature20" . into( ) ] ) ;
195
+ let feature3 = Feature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
196
+
197
+ let raw = vec ! [ feature3. clone( ) , feature2. clone( ) , feature1. clone( ) ] ;
198
+ let ( features, default_len) = order_features_and_count_default_len ( raw) ;
199
+
200
+ assert_eq ! ( features. len( ) , 3 ) ;
201
+ assert_eq ! ( default_len, 0 ) ;
202
+ assert_eq ! ( features. get( 0 ) , Some ( & feature1) ) ;
203
+ assert_eq ! ( features. get( 1 ) , Some ( & feature2) ) ;
204
+ assert_eq ! ( features. get( 2 ) , Some ( & feature3) ) ;
205
+ }
206
+
207
+ #[ test]
208
+ fn test_order_features_and_get_len_single_default ( ) {
209
+ let default = Feature :: new ( DEFAULT_NAME . into ( ) , Vec :: new ( ) ) ;
210
+ let non_default = Feature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
211
+
212
+ let raw = vec ! [ default . clone( ) , non_default. clone( ) ] ;
213
+ let ( features, default_len) = order_features_and_count_default_len ( raw) ;
214
+
215
+ assert_eq ! ( features. len( ) , 2 ) ;
216
+ assert_eq ! ( default_len, 1 ) ;
217
+ assert_eq ! ( features. get( 0 ) , Some ( & default ) ) ;
218
+ assert_eq ! ( features. get( 1 ) , Some ( & non_default) ) ;
219
+ }
220
+ }
0 commit comments