1
1
use crate :: {
2
- db:: types:: Feature ,
2
+ db:: types:: Feature as DbFeature ,
3
3
impl_axum_webpage,
4
4
web:: {
5
5
cache:: CachePolicy ,
@@ -17,13 +17,27 @@ use std::collections::{HashMap, VecDeque};
17
17
const DEFAULT_NAME : & str = "default" ;
18
18
19
19
#[ derive( Debug , Clone , Serialize ) ]
20
- struct DocsFeature {
20
+ struct Feature {
21
21
name : String ,
22
22
subfeatures : Vec < String > ,
23
23
is_default : bool ,
24
24
}
25
25
26
- type AllFeatures = HashMap < String , DocsFeature > ;
26
+ /// The sub-feature enabled by a [`Feature`]
27
+ enum SubFeature {
28
+ /// A normal feature, like `"feature-name"`.
29
+ Feature ( String ) ,
30
+ /// A dependency, like `"dep:package-name"`.
31
+ Dependency ( String ) ,
32
+ /// A dependency feature, like `"package-name?/feature-name"`.
33
+ DependencyFeature {
34
+ dependency : String ,
35
+ optional : bool ,
36
+ feature : String ,
37
+ } ,
38
+ }
39
+
40
+ type AllFeatures = HashMap < String , Feature > ;
27
41
28
42
#[ derive( Debug , Clone , Serialize ) ]
29
43
struct FeaturesPage {
@@ -65,7 +79,7 @@ pub(crate) async fn build_features_handler(
65
79
66
80
let row = sqlx:: query!(
67
81
r#"
68
- SELECT releases.features as "features?: Vec<Feature >"
82
+ SELECT releases.features as "features?: Vec<DbFeature >"
69
83
FROM releases
70
84
INNER JOIN crates ON crates.id = releases.crate_id
71
85
WHERE crates.name = $1 AND releases.version = $2"# ,
@@ -99,7 +113,7 @@ pub(crate) async fn build_features_handler(
99
113
. into_response ( ) )
100
114
}
101
115
102
- fn order_features_and_count_default_len ( raw : Vec < Feature > ) -> ( AllFeatures , Vec < String > , usize ) {
116
+ fn order_features_and_count_default_len ( raw : Vec < DbFeature > ) -> ( AllFeatures , Vec < String > , usize ) {
103
117
let mut all_features = get_all_features ( raw) ;
104
118
let sorted_features = get_sorted_features ( & mut all_features) ;
105
119
@@ -115,7 +129,7 @@ fn order_features_and_count_default_len(raw: Vec<Feature>) -> (AllFeatures, Vec<
115
129
/// and alphabetically otherwise.
116
130
fn get_sorted_features ( all_features : & mut AllFeatures ) -> Vec < String > {
117
131
let mut sorted_features = Vec :: new ( ) ;
118
- let mut working_features: HashMap < & str , & mut DocsFeature > = all_features
132
+ let mut working_features: HashMap < & str , & mut Feature > = all_features
119
133
. iter_mut ( )
120
134
. map ( |( k, v) | ( k. as_str ( ) , v) )
121
135
. collect ( ) ;
@@ -143,14 +157,14 @@ fn get_sorted_features(all_features: &mut AllFeatures) -> Vec<String> {
143
157
sorted_features
144
158
}
145
159
146
- /// Parses the raw [`Feature `] into a map of the more structured [`DocsFeature`].
147
- fn get_all_features ( raw : Vec < Feature > ) -> AllFeatures {
160
+ /// Parses the raw [`DbFeature `] into a map of the more structured [`DocsFeature`].
161
+ fn get_all_features ( raw : Vec < DbFeature > ) -> AllFeatures {
148
162
raw. into_iter ( )
149
163
. filter ( |feature| !feature. is_private ( ) )
150
164
. map ( |feature| {
151
165
(
152
166
feature. name . clone ( ) ,
153
- DocsFeature {
167
+ Feature {
154
168
name : feature. name ,
155
169
subfeatures : feature. subfeatures ,
156
170
is_default : false ,
@@ -168,8 +182,8 @@ mod tests {
168
182
169
183
#[ test]
170
184
fn test_feature_map_filters_private ( ) {
171
- let private1 = Feature :: new ( "_private1" . into ( ) , vec ! [ "feature1" . into( ) ] ) ;
172
- let feature2 = Feature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
185
+ let private1 = DbFeature :: new ( "_private1" . into ( ) , vec ! [ "feature1" . into( ) ] ) ;
186
+ let feature2 = DbFeature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
173
187
174
188
let raw = vec ! [ private1. clone( ) , feature2. clone( ) ] ;
175
189
let all_features = get_all_features ( raw) ;
@@ -181,14 +195,14 @@ mod tests {
181
195
182
196
#[ test]
183
197
fn test_default_tree_structure_with_nested_default ( ) {
184
- let default = Feature :: new ( DEFAULT_NAME . into ( ) , vec ! [ "feature1" . into( ) ] ) ;
185
- let non_default = Feature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
186
- let feature1 = Feature :: new (
198
+ let default = DbFeature :: new ( DEFAULT_NAME . into ( ) , vec ! [ "feature1" . into( ) ] ) ;
199
+ let non_default = DbFeature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
200
+ let feature1 = DbFeature :: new (
187
201
"feature1" . into ( ) ,
188
202
vec ! [ "feature2" . into( ) , "feature3" . into( ) ] ,
189
203
) ;
190
- let feature2 = Feature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
191
- let feature3 = Feature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
204
+ let feature2 = DbFeature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
205
+ let feature3 = DbFeature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
192
206
193
207
let raw = vec ! [
194
208
default . clone( ) ,
@@ -218,12 +232,12 @@ mod tests {
218
232
219
233
#[ test]
220
234
fn test_default_tree_structure_without_default ( ) {
221
- let feature1 = Feature :: new (
235
+ let feature1 = DbFeature :: new (
222
236
"feature1" . into ( ) ,
223
237
vec ! [ "feature2" . into( ) , "feature3" . into( ) ] ,
224
238
) ;
225
- let feature2 = Feature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
226
- let feature3 = Feature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
239
+ let feature2 = DbFeature :: new ( "feature2" . into ( ) , Vec :: new ( ) ) ;
240
+ let feature3 = DbFeature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
227
241
228
242
let raw = vec ! [ feature3. clone( ) , feature2. clone( ) , feature1. clone( ) ] ;
229
243
let mut all_features = get_all_features ( raw) ;
@@ -240,8 +254,8 @@ mod tests {
240
254
241
255
#[ test]
242
256
fn test_default_tree_structure_single_default ( ) {
243
- let default = Feature :: new ( DEFAULT_NAME . into ( ) , Vec :: new ( ) ) ;
244
- let non_default = Feature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
257
+ let default = DbFeature :: new ( DEFAULT_NAME . into ( ) , Vec :: new ( ) ) ;
258
+ let non_default = DbFeature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
245
259
246
260
let raw = vec ! [ default . clone( ) , non_default. clone( ) ] ;
247
261
let mut all_features = get_all_features ( raw) ;
@@ -257,12 +271,12 @@ mod tests {
257
271
258
272
#[ test]
259
273
fn test_order_features_and_get_len_without_default ( ) {
260
- let feature1 = Feature :: new (
274
+ let feature1 = DbFeature :: new (
261
275
"feature1" . into ( ) ,
262
276
vec ! [ "feature10" . into( ) , "feature11" . into( ) ] ,
263
277
) ;
264
- let feature2 = Feature :: new ( "feature2" . into ( ) , vec ! [ "feature20" . into( ) ] ) ;
265
- let feature3 = Feature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
278
+ let feature2 = DbFeature :: new ( "feature2" . into ( ) , vec ! [ "feature20" . into( ) ] ) ;
279
+ let feature3 = DbFeature :: new ( "feature3" . into ( ) , Vec :: new ( ) ) ;
266
280
267
281
let raw = vec ! [ feature3. clone( ) , feature2. clone( ) , feature1. clone( ) ] ;
268
282
let ( _all_features, sorted_features, default_len) =
@@ -277,8 +291,8 @@ mod tests {
277
291
278
292
#[ test]
279
293
fn test_order_features_and_get_len_single_default ( ) {
280
- let default = Feature :: new ( DEFAULT_NAME . into ( ) , Vec :: new ( ) ) ;
281
- let non_default = Feature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
294
+ let default = DbFeature :: new ( DEFAULT_NAME . into ( ) , Vec :: new ( ) ) ;
295
+ let non_default = DbFeature :: new ( "non-default" . into ( ) , Vec :: new ( ) ) ;
282
296
283
297
let raw = vec ! [ default . clone( ) , non_default. clone( ) ] ;
284
298
let ( _all_features, sorted_features, default_len) =
0 commit comments