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: sources.rs
    path of file: ./repos/cryo/crates/freeze/src/types
    
    the code of the file until where you have to start completion: use std::sync::Arc;

use ethers::prelude::*;
use governor::{
    clock::DefaultClock,
    middleware::NoOpMiddleware,
    state::{direct::NotKeyed, InMemoryState},
};
use tokio::{
    sync::{AcquireError, Semaphore, SemaphorePermit},
    task,
};

use crate::CollectError;

/// RateLimiter based on governor crate
pub type RateLimiter = governor::RateLimiter<NotKeyed, InMemoryState, DefaultClock, NoOpMiddleware>;

/// Options for fetching data from node
#[derive(Clone, Debug)]
pub struct Source {
    /// provider
    pub provider: ProviderWrapper,
    /// chain_id of network
    pub chain_id: u64,
    /// number of blocks per log request
    pub inner_request_size: u64,
    /// Maximum chunks collected concurrently
    pub max_concurrent_chunks: Option<u64>,
    /// Rpc Url
    pub rpc_url: String,
    /// semaphore for controlling concurrency
    pub semaphore: Arc<Option<Semaphore>>,
    /// rate limiter for controlling request rate
    pub rate_limiter: Arc<Option<RateLimiter>>,
    /// Labels (the
    
    pub async fn init(rpc_url: Option<String>) -> Result<Source> {
        let rpc_url = parse_rpc_url(rpc_url);
        let provider = Provider::<RetryClient<Http>>::new_client(
            &rpc_url,
            DEFAULT_MAX_RETRIES,
            DEFAULT_INTIAL_BACKOFF,
        )
        .map_err(|_| CollectError::RPCError("could not connect to provider".to_string()))?;
        let chain_id = provider
            .get_chainid()
            .await
            .map_err(|_| CollectError::RPCError("could not get chain_id".to_string()))?
            .as_u64();

        let rate_limiter = None;
        let semaphore = None;

        let provider = Provider::<RetryClient<Http>>::new_client(
            &rpc_url,
            DEFAULT_MAX_RETRIES,
            DEFAULT_INTIAL_BACKOFF,
        )
        .map_err(|_| CollectError::RPCError("could not connect to provider".to_string()))?;

        let source = Source {
            provider: ProviderWrapper::RetryClientHttp(Arc::new(provider)),
            chain_id,
            inner_request_size: DEFAULT_INNER_REQUEST_SIZE,
            max_concurrent_chunks: Some(DEFAULT_MAX_CONCURRENT_CHUNKS),
            rpc_url,
            labels: SourceLabels {
                max_concurrent_requests: Some(DEFAULT_MAX_CONCURRENT_REQUESTS),
                max_requests_per_second: Some(0),
                max_retries: Some(DEFAULT_MAX_RETRIES),
                initial_backoff: Some(DEFAULT_INTIAL_BACKOFF),
            },
            rate_limiter: rate_limiter.into(),
            semaphore: semaphore.into(),
        };

        Ok(source)
    }