fn resolve()

in guppy/src/graph/build.rs [589:652]


    fn resolve<'a>(
        &'a self,
        resolved_name: &str,
        package_id: &PackageId,
    ) -> Result<(&'g str, impl Iterator<Item = &'g Dependency> + 'a), Error> {
        // This method needs to reconcile three separate sources of data:
        // 1. The metadata for each package, which is basically a parsed version of the Cargo.toml
        //    for that package.
        // 2. The list of dependencies for the source package, which is also extracted from
        //    Cargo.toml for that package.
        // 3. The "resolve" section of the manifest, which has resolved names and package IDs (this
        //    is what's passed in).
        //
        // The below algorithm does a pretty job, but there are some edge cases it has trouble
        // handling, primarily around malformed Cargo.toml files. For example, this Cargo.toml file
        // will result in a metadata JSON (as of Rust 1.37) that will parse incorrectly:
        //
        // [dependencies]
        // lazy_static = "1"
        //
        // [build-dependencies]
        // lazy_static_new = { package = "lazy_static", version = "1", optional = true }
        //
        // TODO: Add detection for cases like this.

        // Lookup the package ID in the package data.
        let (_, package_name, version) = self.package_data.get(package_id).ok_or_else(|| {
            Error::PackageGraphConstructError(format!(
                "{}: no package data found for dependency '{}'",
                self.from_id, package_id
            ))
        })?;

        // ---
        // Both the following checks verify against the version as well to allow situations like
        // this to work:
        //
        // [dependencies]
        // lazy_static = "1"
        //
        // [dev-dependencies]
        // lazy_static = "0.2"
        //
        // This needs to be done against the renamed map as well.
        // ---

        // Lookup the name in the renamed map. If a hit is found here we're done.
        if let Some((name, deps)) = self.renamed_map.get(resolved_name) {
            return Ok((*name, deps.matches_for(version)));
        }

        // Lookup the name in the original map.
        let (name, dep_reqs) = self
            .original_map
            .get_key_value(package_name.as_str())
            .ok_or_else(|| {
                Error::PackageGraphConstructError(format!(
                    "{}: no dependency information found for '{}', package ID '{}'",
                    self.from_id, package_name, package_id
                ))
            })?;
        let deps = dep_reqs.matches_for(version);
        Ok((*name, deps))
    }