@@ -9,6 +9,8 @@ use router::Router;
99use serde:: Serialize ;
1010use std:: collections:: { HashMap , VecDeque } ;
1111
12+ const DEFAULT_NAME : & str = "default" ;
13+
1214#[ derive( Debug , Clone , PartialEq , Eq , Serialize ) ]
1315struct FeaturesPage {
1416 metadata : MetaData ,
@@ -38,28 +40,14 @@ pub fn build_features_handler(req: &mut Request) -> IronResult<Response> {
3840
3941 let row = cexpect ! ( req, rows. get( 0 ) ) ;
4042
43+ let mut features = None ;
4144 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+ }
6351
6452 FeaturesPage {
6553 metadata : cexpect ! ( req, MetaData :: from_crate( & mut conn, & name, & version) ) ,
@@ -69,11 +57,26 @@ pub fn build_features_handler(req: &mut Request) -> IronResult<Response> {
6957 . into_response ( req)
7058}
7159
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+
7275fn get_tree_structure_from_default ( feature_map : & mut HashMap < String , Feature > ) -> Vec < Feature > {
7376 let mut features = Vec :: new ( ) ;
7477 let mut queue: VecDeque < String > = VecDeque :: new ( ) ;
7578
76- queue. push_back ( "default" . into ( ) ) ;
79+ queue. push_back ( DEFAULT_NAME . into ( ) ) ;
7780 while !queue. is_empty ( ) {
7881 let name = queue. pop_front ( ) . unwrap ( ) ;
7982 if let Some ( feature) = feature_map. remove ( & name) {
@@ -86,3 +89,132 @@ fn get_tree_structure_from_default(feature_map: &mut HashMap<String, Feature>) -
8689 }
8790 features
8891}
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[ 0 ] , default ) ;
147+ assert_eq ! ( default_tree[ 1 ] , feature1) ;
148+ assert_eq ! ( default_tree[ 2 ] , feature2) ;
149+ assert_eq ! ( default_tree[ 3 ] , 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[ 0 ] , 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[ 0 ] , feature1) ;
203+ assert_eq ! ( features[ 1 ] , feature2) ;
204+ assert_eq ! ( features[ 2 ] , 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[ 0 ] , default ) ;
218+ assert_eq ! ( features[ 1 ] , non_default) ;
219+ }
220+ }
0 commit comments