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: config.rs
    path of file: ./repos/hardhat/crates/edr_napi/src/provider
    
    the code of the file until where you have to start completion: use std::{
    path::PathBuf,
    time::{Duration, SystemTime},
};

use edr_eth::HashMap;
use edr_provider::AccountConfig;
use napi::{
    bindgen_prelude::{BigInt, Buffer},
    Either,
};
use napi_derive::napi;

use crate::{account::GenesisAccount, block::BlobGas, cast::TryCast, config::SpecId};

/// Configuration for a chain
#[napi(object)]
pub struct ChainConfig {
    /// The chain ID
    pub chain_id: BigInt,
    /// The chain's supported hardforks
    pub hardforks: Vec<HardforkActivation>,
}

/// Configuration for forking a blockchain
#[napi(object)]
pub struct ForkConfig {
    /// The URL of the JSON-RPC endpoint to fork from
    pub json_rpc_url: String,
    /// The block number to fork from. If not provided, the latest safe block is
    /// used.
    pub block_number: Option<BigInt>,
    /// The HTTP headers to use when making requests to the JSON-RPC endpoint
    pub http_headers: Option<Vec<HttpHeader>>,
}

#[napi(object)]
pub struct HttpHeader {
    pub name: String,
    pub value: String,
}

/// Configuration for a hardfork activation
#[napi(object)]
pub struct HardforkActi
    
    fn try_from(value: ProviderConfig) -> Result<Self, Self::Error> {
        let chains = value
            .chains
            .into_iter()
            .map(
                |ChainConfig {
                     chain_id,
                     hardforks,
                 }| {
                    let hardforks = hardforks
                        .into_iter()
                        .map(
                            |HardforkActivation {
                                 block_number,
                                 spec_id,
                             }| {
                                let block_number = block_number.try_cast()?;
                                let spec_id = spec_id.into();

                                Ok((block_number, spec_id))
                            },
                        )
                        .collect::<napi::Result<Vec<_>>>()?;

                    let chain_id = chain_id.try_cast()?;
                    Ok((chain_id, edr_eth::spec::HardforkActivations::new(hardforks)))
                },
            )
            .collect::<napi::Result<_>>()?;

        Ok(Self {
            accounts: value
                .genesis_accounts
                .into_iter()
                .map(AccountConfig::try_from)
                .collect::<napi::Result<Vec<_>>>()?,
            allow_blocks_with_same_timestamp: value.allow_blocks_with_same_timestamp,
            allow_unlimited_contract_size: value.allow_unlimited_contract_size,
            bail_on_call_failure: value.bail_on_call_failure,
            bail_on_transaction_failure: value.bail_on_transaction_failure,
            block_gas_limit: value.block_gas_limit.try_cast()?,
            cache_dir: PathBuf::from(
                value
                    .cache_dir
                    .unwrap_or(String::from(edr_defaults::CACHE_DIR)),
            ),
            chain_id: value.chain_id.try_cast()?,
            chains,
            coinbase: value.coinbase.try_cast()?,
            fork: value.fork.map(TryInto::try_into).transpose()?,
            genesis_accounts: HashMap::new(),
            hardfork: value.hardfork.into(),
            initial_base_fee_per_gas: value
                .initial_base_fee_per_gas
                .map(TryCast::try_cast)
                .transpose()?,
            initial_blob_gas: value.initial_blob_gas.map(TryInto::try_into).transpose()?,
            initial_date: value
                .initial_date
                .map(|date| {
                    let elapsed_since_epoch = Duration::from_secs(date.try_cast()?);
                    napi::Result::Ok(SystemTime::UNIX_EPOCH + elapsed_since_epoch)
                })
                .transpose()?,
            initial_parent_beacon_block_root: value
                .initial_parent_beacon_block_root
                .map(TryCast::try_cast)
                .transpose()?,
            mining: value.mining.try_into()?,
            min_gas_price: value.min_gas_price.try_cast()?,
            network_id: value.network_id.try_cast()?,
        })
    }