@@ -5,6 +5,7 @@ use std::{
5
5
} ;
6
6
7
7
use crate :: {
8
+ db:: types:: Feature ,
8
9
docbuilder:: { BuildResult , DocCoverage } ,
9
10
error:: Result ,
10
11
index:: api:: { CrateData , CrateOwner , ReleaseData } ,
@@ -42,6 +43,7 @@ pub(crate) fn add_package_into_database(
42
43
let dependencies = convert_dependencies ( metadata_pkg) ;
43
44
let rustdoc = get_rustdoc ( metadata_pkg, source_dir) . unwrap_or ( None ) ;
44
45
let readme = get_readme ( metadata_pkg, source_dir) . unwrap_or ( None ) ;
46
+ let features = get_features ( metadata_pkg) ;
45
47
let is_library = metadata_pkg. is_library ( ) ;
46
48
47
49
let rows = conn. query (
@@ -52,12 +54,12 @@ pub(crate) fn add_package_into_database(
52
54
homepage_url, description, description_long, readme,
53
55
authors, keywords, have_examples, downloads, files,
54
56
doc_targets, is_library, doc_rustc_version,
55
- documentation_url, default_target
57
+ documentation_url, default_target, features
56
58
)
57
59
VALUES (
58
60
$1, $2, $3, $4, $5, $6, $7, $8, $9,
59
61
$10, $11, $12, $13, $14, $15, $16, $17, $18,
60
- $19, $20, $21, $22, $23, $24, $25
62
+ $19, $20, $21, $22, $23, $24, $25, $26
61
63
)
62
64
ON CONFLICT (crate_id, version) DO UPDATE
63
65
SET release_time = $3,
@@ -82,7 +84,8 @@ pub(crate) fn add_package_into_database(
82
84
is_library = $22,
83
85
doc_rustc_version = $23,
84
86
documentation_url = $24,
85
- default_target = $25
87
+ default_target = $25,
88
+ features = $26
86
89
RETURNING id" ,
87
90
& [
88
91
& crate_id,
@@ -110,6 +113,7 @@ pub(crate) fn add_package_into_database(
110
113
& res. rustc_version ,
111
114
& metadata_pkg. documentation ,
112
115
& default_target,
116
+ & features,
113
117
] ,
114
118
) ?;
115
119
@@ -213,6 +217,35 @@ fn convert_dependencies(pkg: &MetadataPackage) -> Vec<(String, String, String)>
213
217
. collect ( )
214
218
}
215
219
220
+ /// Reads features and converts them to Vec<Feature> with default being first
221
+ fn get_features ( pkg : & MetadataPackage ) -> Vec < Feature > {
222
+ let mut features = Vec :: with_capacity ( pkg. features . len ( ) ) ;
223
+ if let Some ( subfeatures) = pkg. features . get ( "default" ) {
224
+ features. push ( Feature :: new ( "default" . into ( ) , subfeatures. clone ( ) ) ) ;
225
+ } ;
226
+ features. extend (
227
+ pkg. features
228
+ . iter ( )
229
+ . filter ( |( name, _) | !name. eq ( & "default" ) )
230
+ . map ( |( name, subfeatures) | Feature :: new ( name. clone ( ) , subfeatures. clone ( ) ) ) ,
231
+ ) ;
232
+ features. extend ( get_optional_features ( pkg) ) ;
233
+ features
234
+ }
235
+
236
+ fn get_optional_features ( pkg : & MetadataPackage ) -> Vec < Feature > {
237
+ pkg. dependencies
238
+ . iter ( )
239
+ . filter ( |dep| dep. optional )
240
+ . filter ( |dep| {
241
+ pkg. features
242
+ . values ( )
243
+ . any ( |features| features. iter ( ) . any ( |sub| sub. eq ( & dep. name ) ) )
244
+ } )
245
+ . map ( |dep| Feature :: new ( dep. name . clone ( ) , Vec :: new ( ) ) )
246
+ . collect ( )
247
+ }
248
+
216
249
/// Reads readme if there is any read defined in Cargo.toml of a Package
217
250
fn get_readme ( pkg : & MetadataPackage , source_dir : & Path ) -> Result < Option < String > > {
218
251
let readme_path = source_dir. join ( pkg. readme . as_deref ( ) . unwrap_or ( "README.md" ) ) ;
0 commit comments