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: context.rs
    path of file: ./repos/OctoBase/apps/cloud/src
    
    the code of the file until where you have to start completion: use std::{collections::HashMap, path::Path};

use cloud_database::CloudDatabase;
use cloud_infra::{FirebaseContext, KeyContext, MailContext};
use jwst::SearchResults;
use jwst_logger::{error, info, warn};
use jwst_rpc::{BroadcastChannels, BroadcastType, RpcContextImpl};
use jwst_storage::{BlobStorageType, JwstStorage, MixedBucketDBParam};
use tempfile::{tempdir, TempDir};
use tokio::sync::{Mutex, RwLock};

use super::{api::UserChannel, config::Config, utils::create_debug_collaboration_workspace};
use crate::application::blob_service::BlobService;

pub struct Context {
    pub key: KeyContext,
    pub firebase: Mutex<FirebaseContext>,
    pub mail: MailContext,
    pub db: CloudDatabase,
    pub storage: JwstStorage,
    pub user_channel: UserChannel,
    pub channel: BroadcastChannels,
    pub config: Config,
    _dir: Option<TempDir>,
    pub blob_service: 
    
    pub async fn new() -> Context {
        let (_dir, cloud, storage) = if let Ok(url) = dotenvy::var("DATABASE_URL") {
            (None, url.clone(), format!("{url}_binary"))
        } else {
            let (path, dir) = if let Ok(dir) = dotenvy::var("DATABASE_DIR") {
                let dir = Path::new(&dir);
                if !dir.try_exists().unwrap_or(false) {
                    std::fs::create_dir(dir).expect("Cannot create dir");
                }
                (dir.to_path_buf(), None)
            } else {
                let dir = tempdir().expect("Cannot create temp dir");
                warn!("!!! Be careful, the data is stored in a temporary directory !!!");
                (dir.path().to_path_buf(), Some(dir))
            };

            warn!("!!! Please set `DATABASE_URL` in .env file or environmental variable to save your data !!!");
            info!("!!! The data is stored in {} !!!", path.display());
            let cloud = format!("sqlite:{}?mode=rwc", path.join("cloud.db").display());
            let storage = format!("sqlite:{}?mode=rwc", path.join("storage.db").display());

            (dir, cloud, storage)
        };

        let db = CloudDatabase::init_pool(&cloud)
            .await
            .expect("Cannot create cloud database");

        let use_bucket_storage = dotenvy::var("ENABLE_BUCKET_STORAGE").map_or(false, |v| v.eq("true"));

        let storage_type = if use_bucket_storage {
            info!("use database and s3 bucket as blob storage");
            BlobStorageType::MixedBucketDB(
                MixedBucketDBParam::new_from_env()
                    .map_err(|e| format!("failed to load bucket param from env: {}", e))
                    .unwrap(),
            )
        } else {
            info!("use database as blob storage");
            BlobStorageType::DB
        };

        let storage = JwstStorage::new_with_migration(&storage, storage_type)
            .await
            .expect("Cannot create storage");

        let blob_service = BlobService::new();

        if cfg!(debug_assertions) || std::env::var("JWST_DEV").is_ok() {
            create_debug_collaboration_workspace(&db, &storage).await;
        }

        Self {
            _dir,
            // =========== database ===========
            db,
            storage,
            // =========== auth ===========
            key: KeyContext::new(dotenvy::var("SIGN_KEY").ok()).expect("Cannot create key context"),
            firebase: Mutex::new(FirebaseContext::new(
                dotenvy::var("FIREBASE_PROJECT_ID")
                    .map(|id| vec![id])
                    .unwrap_or_else(|_| vec!["pathfinder-52392".into(), "quiet-sanctuary-370417".into()]),
            )),
            // =========== mail ===========
            mail: MailContext::new(dotenvy::var("MAIL_ACCOUNT").ok(), dotenvy::var("MAIL_PASSWORD").ok()),
            // =========== sync channel ===========
            channel: RwLock::new(HashMap::new()),
            user_channel: UserChannel::new(),
            config: Config::new(),
            blob_service,
        }
    }