pub(crate) fn cache_file_computation<
    T: Serialize + DeserializeOwned,
    F: FnOnce(&str) -> Fallible<T>,
>(
    cache_path: &Path,
    input_path: &Path,
    key: &str,
    f: F,
) -> Fallible<T> {
    //NB: astute readers may notice that this unconditionally loads and hashes the input file,
    //without trying to check if the date/time metadata are older than the latest cached entry.
    //This is intentional. It simplifies the code, and the hashing algorithm we use runs at 6GB/s
    //on a crappy Core i5 (https://github.com/Cyan4973/xxHash).  For the kind of workloads are are
    //caching, that's a rounding error
    let mut file = File::open(input_path)?;
    let mut content = Vec::new();
    file.read_to_end(&mut content)?;

    let hash = hash_buf(&content);

    let results_path = cached_results_path(input_path, key, hash);

    //Try to load a cached results file.  If it doesn't exist or there's any kind of error loading
    //it, just invoke the function again
    let abs_path = cache_generated_file(cache_path, &results_path, |abs_path| {
        str::from_utf8(&content)
            .map_err(|e| {
                format_err!(
                    "Input file {} contains invalid UTF-8 text: {}",
                    results_path.display(),
                    e
                )
            })
            .and_then(|str_contents| f(str_contents))
            .and_then(|result| {
                //Result was computed; serialize it back
                save_results::<T>(&abs_path, &result).and(Ok(abs_path))
            })
    })?;

    load_cached_results::<T>(&abs_path)
}
/// Given the path to a file, and a function that takes as an argument a `String` with the contents
/// of that file and returns the (serializable) result of some computation on those contents,
/// implements a cache whereby first the cache directory is checked to see if a previous operation
/// has been attempted on the same file contents.  If found, that version is returned and the
/// function is never invoked.
Given the path to a file, and a function that takes as an argument a `String` with the contents
of that file and returns the (serializable) result of some computation on those contents,
implements a cache whereby first the cache directory is checked to see if a previous operation
has been attempted on the same file contents.  If found, that version is returned and the
function is never invoked.
Given the path to a file and a function that takes as an argument a ` String ` with the contents of that file and returns the ( serializable ) result of some computation on those contents implements a cache whereby first the cache directory is checked to see if a previous operation has been attempted on the same file contents . If found that version is returned and the function is never invoked .
pub(crate) fn cache_file_computation<
    T: Serialize + DeserializeOwned,
    F: FnOnce(&str) -> Fallible<T>,
>(
    cache_path: &Path,
    input_path: &Path,
    key: &str,
    f: F,
) -> Fallible<T> {
    //NB: astute readers may notice that this unconditionally loads and hashes the input file,
    //without trying to check if the date/time metadata are older than the latest cached entry.
    //This is intentional. It simplifies the code, and the hashing algorithm we use runs at 6GB/s
    //on a crappy Core i5 (https://github.com/Cyan4973/xxHash).  For the kind of workloads are are
    //caching, that's a rounding error
    let mut file = File::open(input_path)?;
    let mut content = Vec::new();
    file.read_to_end(&mut content)?;
    let hash = hash_buf(&content);
    let results_path = cached_results_path(input_path, key, hash);
    //Try to load a cached results file.  If it doesn't exist or there's any kind of error loading
    //it, just invoke the function again
    let abs_path = cache_generated_file(cache_path, &results_path, |abs_path| {
        str::from_utf8(&content)
            .map_err(|e| {
                format_err!(
                    "Input file {} contains invalid UTF-8 text: {}",
                    results_path.display(),
                    e
                )
            })
            .and_then(|str_contents| f(str_contents))
            .and_then(|result| {
                //Result was computed; serialize it back
                save_results::<T>(&abs_path, &result).and(Ok(abs_path))
            })
    })?;
    load_cached_results::<T>(&abs_path)
}
pub ( crate ) fn cache_file_computation < T : Serialize + DeserializeOwned , F : FnOnce ( & str ) -> Fallible < T > , > ( cache_path : & Path , input_path : & Path , key : & str , f : F , ) -> Fallible < T > { //NB: astute readers may notice that this unconditionally loads and hashes the input file, //without trying to check if the date/time metadata are older than the latest cached entry. //This is intentional. It simplifies the code, and the hashing algorithm we use runs at 6GB/s //on a crappy Core i5 (https://github.com/Cyan4973/xxHash).  For the kind of workloads are are //caching, that's a rounding error let mut file = File :: open ( input_path ) ? ; let mut content = Vec :: new ( ) ; file . read_to_end ( & mut content ) ? ; let hash = hash_buf ( & content ) ; let results_path = cached_results_path ( input_path , key , hash ) ; //Try to load a cached results file.  If it doesn't exist or there's any kind of error loading //it, just invoke the function again let abs_path = cache_generated_file ( cache_path , & results_path , | abs_path | { str :: from_utf8 ( & content ) . map_err ( | e | { format_err ! ( " " results_path display ( ) e ) } ) . and_then ( | str_contents | f ( str_contents ) ) . and_then ( | result | { //Result was computed; serialize it back save_results :: < T > ( & abs_path , & result ) . and ( Ok ( abs_path ) ) } ) } ) ? ; load_cached_results :: < T > ( & abs_path ) }
Given the path to a file, and a function that takes as an argument a `String` with the contents
of that file and returns the (serializable) result of some computation on those contents,
implements a cache whereby first the cache directory is checked to see if a previous operation
has been attempted on the same file contents.
Given the path to a file and a function that takes as an argument a ` String ` with the contents of that file and returns the ( serializable ) result of some computation on those contents implements a cache whereby first the cache directory is checked to see if a previous operation has been attempted on the same file contents .
cache_path
&Path
input_path
&Path
key
&str
f
F
cache_path
&Path
input_path
&Path
key
&str
f
F