@@ -5,6 +5,7 @@ use std::{
55} ;
66
77use crate :: {
8+ db:: types:: Feature ,
89 docbuilder:: { BuildResult , DocCoverage } ,
910 error:: Result ,
1011 index:: api:: { CrateData , CrateOwner , ReleaseData } ,
@@ -42,6 +43,7 @@ pub(crate) fn add_package_into_database(
4243 let dependencies = convert_dependencies ( metadata_pkg) ;
4344 let rustdoc = get_rustdoc ( metadata_pkg, source_dir) . unwrap_or ( None ) ;
4445 let readme = get_readme ( metadata_pkg, source_dir) . unwrap_or ( None ) ;
46+ let features = get_features ( metadata_pkg) ;
4547 let is_library = metadata_pkg. is_library ( ) ;
4648
4749 let rows = conn. query (
@@ -52,12 +54,12 @@ pub(crate) fn add_package_into_database(
5254 homepage_url, description, description_long, readme,
5355 authors, keywords, have_examples, downloads, files,
5456 doc_targets, is_library, doc_rustc_version,
55- documentation_url, default_target
57+ documentation_url, default_target, features
5658 )
5759 VALUES (
5860 $1, $2, $3, $4, $5, $6, $7, $8, $9,
5961 $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
6163 )
6264 ON CONFLICT (crate_id, version) DO UPDATE
6365 SET release_time = $3,
@@ -82,7 +84,8 @@ pub(crate) fn add_package_into_database(
8284 is_library = $22,
8385 doc_rustc_version = $23,
8486 documentation_url = $24,
85- default_target = $25
87+ default_target = $25,
88+ features = $26
8689 RETURNING id" ,
8790 & [
8891 & crate_id,
@@ -110,6 +113,7 @@ pub(crate) fn add_package_into_database(
110113 & res. rustc_version ,
111114 & metadata_pkg. documentation ,
112115 & default_target,
116+ & features,
113117 ] ,
114118 ) ?;
115119
@@ -213,6 +217,30 @@ fn convert_dependencies(pkg: &MetadataPackage) -> Vec<(String, String, String)>
213217 . collect ( )
214218}
215219
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 != "default" )
230+ . map ( |( name, subfeatures) | Feature :: new ( name. clone ( ) , subfeatures. clone ( ) ) ) ,
231+ ) ;
232+ features. extend ( get_optional_dependencies ( pkg) ) ;
233+ features
234+ }
235+
236+ fn get_optional_dependencies ( pkg : & MetadataPackage ) -> Vec < Feature > {
237+ pkg. dependencies
238+ . iter ( )
239+ . filter ( |dep| dep. optional )
240+ . map ( |dep| Feature :: new ( dep. name . clone ( ) , Vec :: new ( ) ) )
241+ . collect ( )
242+ }
243+
216244/// Reads readme if there is any read defined in Cargo.toml of a Package
217245fn get_readme ( pkg : & MetadataPackage , source_dir : & Path ) -> Result < Option < String > > {
218246 let readme_path = source_dir. join ( pkg. readme . as_deref ( ) . unwrap_or ( "README.md" ) ) ;
0 commit comments