fn add_edges()

in guppy/src/graph/feature/build.rs [365:455]


    fn add_edges(
        &mut self,
        from_node: FeatureNode,
        to_nodes_edges: impl IntoIterator<Item = (FeatureNode, FeatureEdge)>,
    ) {
        // The from node should always be present because it is a known node.
        let from_ix = self.lookup_node(&from_node).unwrap_or_else(|| {
            panic!(
                "while adding feature edges, missing 'from': {:?}",
                from_node
            );
        });
        to_nodes_edges.into_iter().for_each(|(to_node, edge)| {
            let to_ix = self.lookup_node(&to_node).unwrap_or_else(|| {
                panic!("while adding feature edges, missing 'to': {:?}", to_node)
            });

            match self.graph.find_edge(from_ix, to_ix) {
                Some(edge_ix) => {
                    // The edge already exists. This could be an upgrade from a cross link to a
                    // feature dependency, for example:
                    //
                    // [package]
                    // name = "main"
                    //
                    // [dependencies]
                    // dep = { ..., optional = true }
                    //
                    // [features]
                    // "feat" = ["dep/feat", "dep"]
                    //
                    // "dep/feat" causes a cross link to be created from "main/feat" to "main/dep".
                    // However, the "dep" encountered later upgrades this link to a feature
                    // dependency.
                    //
                    // This could also be an upgrade from a weak to a non-weak dependency:
                    //
                    // [features]
                    // feat = ["dep?/feat", "dep/feat2"]
                    let old_edge = self
                        .graph
                        .edge_weight_mut(edge_ix)
                        .expect("this edge was just found");
                    #[allow(clippy::single_match)]
                    match (old_edge, edge) {
                        (
                            FeatureEdge::NamedFeatureWithSlash {
                                weak_index: old_weak_index,
                                ..
                            },
                            FeatureEdge::NamedFeatureWithSlash { weak_index, .. },
                        ) => {
                            if old_weak_index.is_some() && weak_index.is_some() {
                                debug_assert_eq!(
                                    *old_weak_index, weak_index,
                                    "weak indexes should match if some"
                                );
                            }
                            // Upgrade this edge from weak to non-weak.
                            if weak_index.is_none() {
                                *old_weak_index = None;
                            }
                        }
                        (
                            old_edge @ FeatureEdge::NamedFeatureWithSlash { .. },
                            edge @ FeatureEdge::NamedFeature
                            | edge @ FeatureEdge::NamedFeatureDepColon(_),
                        ) => {
                            // Upgrade this edge from / conditional to dep: conditional or unconditional.
                            *old_edge = edge;
                        }
                        (
                            old_edge @ FeatureEdge::NamedFeatureDepColon(_),
                            edge @ FeatureEdge::NamedFeature,
                        ) => {
                            // Upgrade this edge from dep: conditional to unconditional.
                            // XXX: can this ever happen?
                            *old_edge = edge;
                        }

                        _ => {
                            // In all other cases, leave the old edge alone.
                        }
                    }
                }
                None => {
                    self.graph.add_edge(from_ix, to_ix, edge);
                }
            }
        })
    }