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: diff.rs
    path of file: ./repos/reth/bin/reth/src/commands/db
    
    the code of the file until where you have to start completion: use crate::{
    args::DatabaseArgs,
    dirs::{DataDirPath, PlatformPath},
    utils::DbTool,
};
use clap::Parser;
use reth_db::{
    cursor::DbCursorRO, database::Database, mdbx::DatabaseArguments, open_db_read_only,
    table::Table, transaction::DbTx, AccountChangeSets, AccountsHistory, AccountsTrie,
    BlockBodyIndices, BlockOmmers, BlockWithdrawals, Bytecodes, CanonicalHeaders, DatabaseEnv,
    HashedAccounts, HashedStorages, HeaderNumbers, HeaderTerminalDifficulties, Headers,
    PlainAccountState, PlainStorageState, PruneCheckpoints, Receipts, StageCheckpointProgresses,
    StageCheckpoints, StorageChangeSets, StoragesHistory, StoragesTrie, Tables, TransactionBlocks,
    TransactionHashNumbers, TransactionSenders, Transactions,
};
use std::{
    collections::HashMap,
    fmt::Debug,
    fs::{self, File},
    hash::Hash,
    io::Write,
    path::{Path, PathBuf},
};
use tracing::info;

#[derive(Parser, Debug)]
/// The arguments for the `reth db diff` command
pub struct Command {
    /// The path to the data dir for all reth files and subdirectories.
    #[arg(long, verbatim_doc_comment)]
    secondary_datadir: PlatformPath<DataDirPath>,

    /// Arguments for the second database
    #[command(flatten)]
    second_db: DatabaseArgs,

    /// The table name to diff. If not specified, all tables are diffed.
    #[arg(long, verbatim_doc_comment)]
    table: Option<Tables>,

    /// The output directory for the diff report.
    #[arg(long, verbatim_doc_comment)]
    output: PlatformPath<PathBuf>,
}

impl Command {
    /// Execute the `db diff` command.
    ///
    /// This first opens the `db/` folder from the secondary datadir, where the second database is
    /// opened read-only.
    ///
    /// The tool will then iterate through all key-value pairs for the primary and secondary
    /// databases. The value for each key will be compared with its corresponding value in the
    /// other database
    
    pub fn execute(self, tool: &DbTool<DatabaseEnv>) -> eyre::Result<()> {
        // open second db
        let second_db_path: PathBuf = self.secondary_datadir.join("db").into();
        let second_db = open_db_read_only(
            &second_db_path,
            DatabaseArguments::default().log_level(self.second_db.log_level),
        )?;

        let tables = match &self.table {
            Some(table) => std::slice::from_ref(table),
            None => Tables::ALL,
        };

        for table in tables {
            let primary_tx = tool.provider_factory.db_ref().tx()?;
            let secondary_tx = second_db.tx()?;

            let output_dir = self.output.clone();
            match table {
                Tables::CanonicalHeaders => {
                    find_diffs::<CanonicalHeaders>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::HeaderTerminalDifficulties => {
                    find_diffs::<HeaderTerminalDifficulties>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::HeaderNumbers => {
                    find_diffs::<HeaderNumbers>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::Headers => find_diffs::<Headers>(primary_tx, secondary_tx, output_dir)?,
                Tables::BlockBodyIndices => {
                    find_diffs::<BlockBodyIndices>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::BlockOmmers => {
                    find_diffs::<BlockOmmers>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::BlockWithdrawals => {
                    find_diffs::<BlockWithdrawals>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::TransactionBlocks => {
                    find_diffs::<TransactionBlocks>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::Transactions => {
                    find_diffs::<Transactions>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::TransactionHashNumbers => {
                    find_diffs::<TransactionHashNumbers>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::Receipts => find_diffs::<Receipts>(primary_tx, secondary_tx, output_dir)?,
                Tables::PlainAccountState => {
                    find_diffs::<PlainAccountState>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::PlainStorageState => {
                    find_diffs::<PlainStorageState>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::Bytecodes => find_diffs::<Bytecodes>(primary_tx, secondary_tx, output_dir)?,
                Tables::AccountsHistory => {
                    find_diffs::<AccountsHistory>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::StoragesHistory => {
                    find_diffs::<StoragesHistory>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::AccountChangeSets => {
                    find_diffs::<AccountChangeSets>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::StorageChangeSets => {
                    find_diffs::<StorageChangeSets>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::HashedAccounts => {
                    find_diffs::<HashedAccounts>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::HashedStorages => {
                    find_diffs::<HashedStorages>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::AccountsTrie => {
                    find_diffs::<AccountsTrie>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::StoragesTrie => {
                    find_diffs::<StoragesTrie>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::TransactionSenders => {
                    find_diffs::<TransactionSenders>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::StageCheckpoints => {
                    find_diffs::<StageCheckpoints>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::StageCheckpointProgresses => {
                    find_diffs::<StageCheckpointProgresses>(primary_tx, secondary_tx, output_dir)?
                }
                Tables::PruneCheckpoints => {
                    find_diffs::<PruneCheckpoints>(primary_tx, secondary_tx, output_dir)?
                }
            };
        }

        Ok(())
    }