in guppy/src/graph/feature/build.rs [100:204]
fn nodes_for_named_feature_dep(
&mut self,
metadata: PackageMetadata<'_>,
from_label: FeatureLabel<'_>,
feature_dep: &NamedFeatureDep,
dep_name_to_link: &HashMap<&str, PackageLink>,
) -> SmallVec<[(FeatureNode, FeatureEdge); 3]> {
let mut nodes_edges: SmallVec<[(FeatureNode, FeatureEdge); 3]> = SmallVec::new();
match feature_dep {
NamedFeatureDep::DependencyNamedFeature {
dep_name,
feature,
weak,
} => {
if let Some(link) = dep_name_to_link.get(dep_name.as_ref()) {
let weak_index = weak.then(|| self.weak.insert(link.edge_ix()));
// Dependency from (`main`, `a`) to (`dep, `foo`)
if let Some(cross_node) = self.make_named_feature_node(
&metadata,
from_label,
&link.to(),
FeatureLabel::Named(feature.as_ref()),
true,
) {
// This is a cross-package link. The platform-specific
// requirements still apply, so grab them from the
// PackageLink.
nodes_edges.push((
cross_node,
Self::make_named_feature_cross_edge(link, weak_index),
));
};
// If the package is present as an optional dependency, it is
// implicitly activated by the feature:
// from (`main`, `a`) to (`main`, `dep:dep`)
if let Some(same_node) = self.make_named_feature_node(
&metadata,
from_label,
&metadata,
FeatureLabel::OptionalDependency(dep_name),
// Don't warn if this dep isn't optional.
false,
) {
nodes_edges.push((
same_node,
Self::make_named_feature_cross_edge(link, weak_index),
));
}
// Finally, (`main`, `a`) to (`main`, `dep`) -- if this is a non-weak dependency
// and a named feature by this name is present, it also gets activated (even if
// the named feature has no relation to the optional dependency).
if !*weak {
if let Some(same_named_feature_node) = self.make_named_feature_node(
&metadata,
from_label,
&metadata,
FeatureLabel::Named(dep_name),
// Don't warn if this dep isn't optional.
false,
) {
nodes_edges.push((
same_named_feature_node,
Self::make_named_feature_cross_edge(link, None),
));
}
}
}
}
NamedFeatureDep::NamedFeature(feature_name) => {
if let Some(same_node) = self.make_named_feature_node(
&metadata,
from_label,
&metadata,
FeatureLabel::Named(feature_name.as_ref()),
true,
) {
nodes_edges.push((same_node, FeatureEdge::NamedFeature));
}
}
NamedFeatureDep::OptionalDependency(dep_name) => {
if let Some(same_node) = self.make_named_feature_node(
&metadata,
from_label,
&metadata,
FeatureLabel::OptionalDependency(dep_name.as_ref()),
true,
) {
if let Some(link) = dep_name_to_link.get(dep_name.as_ref()) {
nodes_edges.push((
same_node,
FeatureEdge::NamedFeatureDepColon(
Self::make_full_conditional_link_impl(link),
),
));
}
}
}
};
nodes_edges
}