You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: books.rs
    path of file: ./repos/kani/tools/bookrunner/src
    
    the code of the file until where you have to start completion: // Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Utilities to extract examples from Rust books, run them through Kani, and
//! display their results.

extern crate rustc_span;

use crate::{
    bookrunner,
    litani::{Litani, LitaniPipeline, LitaniRun},
    util::{self, FailStep, TestProps},
};
use inflector::cases::{snakecase::to_snake_case, titlecase::to_title_case};
use pulldown_cmark::{Event, Parser, Tag, TagEnd};
use rustc_span::edition::Edition;
use rustdoc::{
    doctest::{make_test, Tester},
    html::markdown::{find_testable_code, ErrorCodes, Ignore, LangString},
};
use std::{
    collections::{HashMap, HashSet},
    ffi::OsStr,
    fmt::Write,
    fs,
    io::BufReader,
    iter::FromIterator,
    path::{Path, PathBuf},
    str::FromStr,
};
use walkdir::WalkDir;

// Books may include a `SUMMARY.md` file or not. If they do, the info in
// `SummaryD
    
    fn parse_hierarchy_without_summary(&mut self) {
        let directory_data = self.directory_data.as_ref().unwrap();
        let src = &directory_data.src;
        let dest = &directory_data.dest;
        let mut src_prefix: PathBuf = src.clone();
        let mut dest_prefix: PathBuf = dest.clone();
        for entry in WalkDir::new(&src_prefix) {
            let entry = entry.unwrap().into_path();
            // `WalkDir` returns entries in a depth-first fashion. Once we are done
            // processing a directory, it will jump to a different child entry of a
            // predecessor. To copy examples to the correct location, we need to
            // know how far back we jumped and update `dest_prefix` accordingly.
            while !entry.starts_with(&src_prefix) {
                src_prefix.pop();
                dest_prefix.pop();
            }
            if entry.is_dir() {
                src_prefix.push(entry.file_name().unwrap());
                // Follow the book's title case format for directories.
                dest_prefix.push(to_title_case(entry.file_name().unwrap().to_str().unwrap()));
            } else {
                // Only process markdown files.
                if entry.extension() == Some(OsStr::new("md")) {
                    let entry_stem = entry.file_stem().unwrap().to_str().unwrap();
                    // If a file has the stem name as a sibling directory...
                    if src_prefix.join(entry.file_stem().unwrap()).exists() {
                        // Its extracted examples should reside under that
                        // directory.
                        self.hierarchy
                            .insert(entry.clone(), dest_prefix.join(to_title_case(entry_stem)));
                    } else {
                        // Otherwise, follow the book's snake case format for files.
                        self.hierarchy
                            .insert(entry.clone(), dest_prefix.join(to_snake_case(entry_stem)));
                    }
                }
            }
        }
    }