pub fn parse(
        index_version: Option<&str>,
        root: &Path,
        cache_root: &Path,
        relative: &Path,
        source_id: SourceId,
        load: &mut dyn RegistryData,
        config: &Config,
    ) -> CargoResult<Option<Summaries>> {
        // First up, attempt to load the cache. This could fail for all manner
        // of reasons, but consider all of them non-fatal and just log their
        // occurrence in case anyone is debugging anything.
        let cache_path = cache_root.join(relative);
        let mut cache_contents = None;
        if let Some(index_version) = index_version {
            match fs::read(&cache_path) {
                Ok(contents) => match Summaries::parse_cache(contents, index_version) {
                    Ok(s) => {
                        log::debug!("fast path for registry cache of {:?}", relative);
                        if cfg!(debug_assertions) {
                            cache_contents = Some(s.raw_data);
                        } else {
                            return Ok(Some(s));
                        }
                    }
                    Err(e) => {
                        log::debug!("failed to parse {:?} cache: {}", relative, e);
                    }
                },
                Err(e) => log::debug!("cache missing for {:?} error: {}", relative, e),
            }
        }

        // This is the fallback path where we actually talk to libgit2 to load
        // information. Here we parse every single line in the index (as we need
        // to find the versions)
        log::debug!("slow path for {:?}", relative);
        let mut ret = Summaries::default();
        let mut hit_closure = false;
        let mut cache_bytes = None;
        let err = load.load(root, relative, &mut |contents| {
            ret.raw_data = contents.to_vec();
            let mut cache = SummariesCache::default();
            hit_closure = true;
            for line in split(contents, b'\n') {
                // Attempt forwards-compatibility on the index by ignoring
                // everything that we ourselves don't understand, that should
                // allow future cargo implementations to break the
                // interpretation of each line here and older cargo will simply
                // ignore the new lines.
                let summary = match IndexSummary::parse(config, line, source_id) {
                    Ok(summary) => summary,
                    Err(e) => {
                        // This should only happen when there is an index
                        // entry from a future version of cargo that this
                        // version doesn't understand. Hopefully, those future
                        // versions of cargo correctly set INDEX_V_MAX and
                        // CURRENT_CACHE_VERSION, otherwise this will skip
                        // entries in the cache preventing those newer
                        // versions from reading them (that is, until the
                        // cache is rebuilt).
                        log::info!("failed to parse {:?} registry package: {}", relative, e);
                        continue;
                    }
                };
                let version = summary.summary.package_id().version().clone();
                cache.versions.push((version.clone(), line));
                ret.versions.insert(version, summary.into());
            }
            if let Some(index_version) = index_version {
                cache_bytes = Some(cache.serialize(index_version));
            }
            Ok(())
        });

        // We ignore lookup failures as those are just crates which don't exist
        // or we haven't updated the registry yet. If we actually ran the
        // closure though then we care about those errors.
        if !hit_closure {
            debug_assert!(cache_contents.is_none());
            return Ok(None);
        }
        err?;

        // If we've got debug assertions enabled and the cache was previously
        // present and considered fresh this is where the debug assertions
        // actually happens to verify that our cache is indeed fresh and
        // computes exactly the same value as before.
        if cfg!(debug_assertions) && cache_contents.is_some() && cache_bytes != cache_contents {
            panic!(
                "original cache contents:\n{:?}\n\
                 does not equal new cache contents:\n{:?}\n",
                cache_contents.as_ref().map(|s| String::from_utf8_lossy(s)),
                cache_bytes.as_ref().map(|s| String::from_utf8_lossy(s)),
            );
        }

        // Once we have our `cache_bytes` which represents the `Summaries` we're
        // about to return, write that back out to disk so future Cargo
        // invocations can use it.
        //
        // This is opportunistic so we ignore failure here but are sure to log
        // something in case of error.
        if let Some(cache_bytes) = cache_bytes {
            if paths::create_dir_all(cache_path.parent().unwrap()).is_ok() {
                let path = Filesystem::new(cache_path.clone());
                config.assert_package_cache_locked(&path);
                if let Err(e) = fs::write(cache_path, cache_bytes) {
                    log::info!("failed to write cache: {}", e);
                }
            }
        }

        Ok(Some(ret))
    }
/// Parse out a `Summaries` instances from on-disk state.
///
/// This will attempt to prefer parsing a previous cache file that already
/// exists from a previous invocation of Cargo (aka you're typing `cargo
/// build` again after typing it previously). If parsing fails or the cache
/// isn't found, then we take a slower path which loads the full descriptor
/// for `relative` from the underlying index (aka typically libgit2 with
/// crates.io) and then parse everything in there.
///
/// * `index_version` - a version string to describe the current state of
///   the index which for remote registries is the current git sha and
///   for local registries is not available.
/// * `root` - this is the root argument passed to `load`
/// * `cache_root` - this is the root on the filesystem itself of where to
///   store cache files.
/// * `relative` - this is the file we're loading from cache or the index
///   data
/// * `source_id` - the registry's SourceId used when parsing JSON blobs to
///   create summaries.
/// * `load` - the actual index implementation which may be very slow to
///   call. We avoid this if we can.
Parse out a `Summaries` instances from on-disk state.
This will attempt to prefer parsing a previous cache file that already
exists from a previous invocation of Cargo (aka you're typing `cargo
build` again after typing it previously). If parsing fails or the cache
isn't found, then we take a slower path which loads the full descriptor
for `relative` from the underlying index (aka typically libgit2 with
crates.io) and then parse everything in there.

`index_version` - a version string to describe the current state of
the index which for remote registries is the current git sha and
for local registries is not available.
Parse out a ` Summaries ` instances from on - disk state . This will attempt to prefer parsing a previous cache file that already exists from a previous invocation of Cargo ( aka you ' re typing ` cargo build ` again after typing it previously ) . If parsing fails or the cache isn ' t found then we take a slower path which loads the full descriptor for ` relative ` from the underlying index ( aka typically libgit2 with crates . io ) and then parse everything in there . ` index_version ` - a version string to describe the current state of the index which for remote registries is the current git sha and for local registries is not available .
pub fn parse(
        index_version: Option<&str>,
        root: &Path,
        cache_root: &Path,
        relative: &Path,
        source_id: SourceId,
        load: &mut dyn RegistryData,
        config: &Config,
    ) -> CargoResult<Option<Summaries>> {
        // First up, attempt to load the cache. This could fail for all manner
        // of reasons, but consider all of them non-fatal and just log their
        // occurrence in case anyone is debugging anything.
        let cache_path = cache_root.join(relative);
        let mut cache_contents = None;
        if let Some(index_version) = index_version {
            match fs::read(&cache_path) {
                Ok(contents) => match Summaries::parse_cache(contents, index_version) {
                    Ok(s) => {
                        log::debug!("fast path for registry cache of {:?}", relative);
                        if cfg!(debug_assertions) {
                            cache_contents = Some(s.raw_data);
                        } else {
                            return Ok(Some(s));
                        }
                    }
                    Err(e) => {
                        log::debug!("failed to parse {:?} cache: {}", relative, e);
                    }
                },
                Err(e) => log::debug!("cache missing for {:?} error: {}", relative, e),
            }
        }
        // This is the fallback path where we actually talk to libgit2 to load
        // information. Here we parse every single line in the index (as we need
        // to find the versions)
        log::debug!("slow path for {:?}", relative);
        let mut ret = Summaries::default();
        let mut hit_closure = false;
        let mut cache_bytes = None;
        let err = load.load(root, relative, &mut |contents| {
            ret.raw_data = contents.to_vec();
            let mut cache = SummariesCache::default();
            hit_closure = true;
            for line in split(contents, b'\n') {
                // Attempt forwards-compatibility on the index by ignoring
                // everything that we ourselves don't understand, that should
                // allow future cargo implementations to break the
                // interpretation of each line here and older cargo will simply
                // ignore the new lines.
                let summary = match IndexSummary::parse(config, line, source_id) {
                    Ok(summary) => summary,
                    Err(e) => {
                        // This should only happen when there is an index
                        // entry from a future version of cargo that this
                        // version doesn't understand. Hopefully, those future
                        // versions of cargo correctly set INDEX_V_MAX and
                        // CURRENT_CACHE_VERSION, otherwise this will skip
                        // entries in the cache preventing those newer
                        // versions from reading them (that is, until the
                        // cache is rebuilt).
                        log::info!("failed to parse {:?} registry package: {}", relative, e);
                        continue;
                    }
                };
                let version = summary.summary.package_id().version().clone();
                cache.versions.push((version.clone(), line));
                ret.versions.insert(version, summary.into());
            }
            if let Some(index_version) = index_version {
                cache_bytes = Some(cache.serialize(index_version));
            }
            Ok(())
        });
        // We ignore lookup failures as those are just crates which don't exist
        // or we haven't updated the registry yet. If we actually ran the
        // closure though then we care about those errors.
        if !hit_closure {
            debug_assert!(cache_contents.is_none());
            return Ok(None);
        }
        err?;
        // If we've got debug assertions enabled and the cache was previously
        // present and considered fresh this is where the debug assertions
        // actually happens to verify that our cache is indeed fresh and
        // computes exactly the same value as before.
        if cfg!(debug_assertions) && cache_contents.is_some() && cache_bytes != cache_contents {
            panic!(
                "original cache contents:\n{:?}\n\
                 does not equal new cache contents:\n{:?}\n",
                cache_contents.as_ref().map(|s| String::from_utf8_lossy(s)),
                cache_bytes.as_ref().map(|s| String::from_utf8_lossy(s)),
            );
        }
        // Once we have our `cache_bytes` which represents the `Summaries` we're
        // about to return, write that back out to disk so future Cargo
        // invocations can use it.
        //
        // This is opportunistic so we ignore failure here but are sure to log
        // something in case of error.
        if let Some(cache_bytes) = cache_bytes {
            if paths::create_dir_all(cache_path.parent().unwrap()).is_ok() {
                let path = Filesystem::new(cache_path.clone());
                config.assert_package_cache_locked(&path);
                if let Err(e) = fs::write(cache_path, cache_bytes) {
                    log::info!("failed to write cache: {}", e);
                }
            }
        }
        Ok(Some(ret))
    }
pub fn parse ( index_version : Option < & str > , root : & Path , cache_root : & Path , relative : & Path , source_id : SourceId , load : & mut dyn RegistryData , config : & Config , ) -> CargoResult < Option < Summaries > > { // First up, attempt to load the cache. This could fail for all manner // of reasons, but consider all of them non-fatal and just log their // occurrence in case anyone is debugging anything. let cache_path = cache_root . join ( relative ) ; let mut cache_contents = None ; if let Some ( index_version ) = index_version { match fs :: read ( & cache_path ) { Ok ( contents ) => match Summaries :: parse_cache ( contents , index_version ) { Ok ( s ) => { log :: debug ! ( " " relative ) ; if cfg ! ( debug_assertions ) { cache_contents = Some ( s . raw_data ) ; } else { return Ok ( Some ( s ) ) ; } } Err ( e ) => { log :: debug ! ( " " relative e ) ; } } , Err ( e ) => log :: debug ! ( " " relative e ) , } } // This is the fallback path where we actually talk to libgit2 to load // information. Here we parse every single line in the index (as we need // to find the versions) log :: debug ! ( " " relative ) ; let mut ret = Summaries :: default ( ) ; let mut hit_closure = false ; let mut cache_bytes = None ; let err = load . load ( root , relative , & mut | contents | { ret . raw_data = contents . to_vec ( ) ; let mut cache = SummariesCache :: default ( ) ; hit_closure = true ; for line in split ( contents , b'\n' ) { // Attempt forwards-compatibility on the index by ignoring // everything that we ourselves don't understand, that should // allow future cargo implementations to break the // interpretation of each line here and older cargo will simply // ignore the new lines. let summary = match IndexSummary :: parse ( config , line , source_id ) { Ok ( summary ) => summary , Err ( e ) => { // This should only happen when there is an index // entry from a future version of cargo that this // version doesn't understand. Hopefully, those future // versions of cargo correctly set INDEX_V_MAX and // CURRENT_CACHE_VERSION, otherwise this will skip // entries in the cache preventing those newer // versions from reading them (that is, until the // cache is rebuilt). log :: info ! ( " " relative e ) ; continue ; } } ; let version = summary . summary . package_id ( ) . version ( ) . clone ( ) ; cache . versions . push ( ( version . clone ( ) , line ) ) ; ret . versions . insert ( version , summary . into ( ) ) ; } if let Some ( index_version ) = index_version { cache_bytes = Some ( cache . serialize ( index_version ) ) ; } Ok ( ( ) ) } ) ; // We ignore lookup failures as those are just crates which don't exist // or we haven't updated the registry yet. If we actually ran the // closure though then we care about those errors. if ! hit_closure { debug_assert ! ( cache_contents is_none ( ) ) ; return Ok ( None ) ; } err ? ; // If we've got debug assertions enabled and the cache was previously // present and considered fresh this is where the debug assertions // actually happens to verify that our cache is indeed fresh and // computes exactly the same value as before. if cfg ! ( debug_assertions ) && cache_contents . is_some ( ) && cache_bytes != cache_contents { panic ! ( " \n \n \
 \n \n " cache_contents as_ref ( ) map ( s String from_utf8_lossy ( s ) ) cache_bytes as_ref ( ) map ( s String from_utf8_lossy ( s ) ) ) ; } // Once we have our `cache_bytes` which represents the `Summaries` we're // about to return, write that back out to disk so future Cargo // invocations can use it. // // This is opportunistic so we ignore failure here but are sure to log // something in case of error. if let Some ( cache_bytes ) = cache_bytes { if paths :: create_dir_all ( cache_path . parent ( ) . unwrap ( ) ) . is_ok ( ) { let path = Filesystem :: new ( cache_path . clone ( ) ) ; config . assert_package_cache_locked ( & path ) ; if let Err ( e ) = fs :: write ( cache_path , cache_bytes ) { log :: info ! ( " " e ) ; } } } Ok ( Some ( ret ) ) }
Parse out a `Summaries` instances from on-disk state.
Parse out a ` Summaries ` instances from on - disk state .
index_version
Option<&str>
root
&Path
cache_root
&Path
relative
&Path
source_id
SourceId
load
&mut dyn RegistryData
config
&Config
index_version
Option<&str>
root
&Path
cache_root
&Path
relative
&Path
source_id
SourceId
load
&mut dyn RegistryData
config
&Config