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: lib.rs
    path of file: ./repos/nearcore/pytest/tools/mirror/contract/src
    
    the code of the file until where you have to start completion: //! Contract that adds keys and creates accounts

use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::{env, near_bindgen, AccountId, Balance, Promise, PublicKey};
use std::str::FromStr;

#[near_bindgen]
#[derive(Default, BorshDeserialize, BorshSerialize)]
pub struct KeyAdder {}

#[near_bindgen]
i
    
    pub fn add_key(&mut self, public_key: String) -> Promise {
        let signer_id = env::signer_account_id();
        if signer_id == env::current_account_id() {
            let public_key = PublicKey::from_str(&public_key).unwrap();
            Promise::new(signer_id).add_full_access_key(public_key)
        } else {
            // here we call the contract again on the signer, assuming that
            // it has been deployed. This lets us test the two cases, one where
            // we have a local receipt generated by a tx with the same signer and receiver,
            // and one where test1 calls test0, and what we want to look for on chain is
            // the receipt generated by this cross-contract call here
            Self::ext(signer_id).add_key(public_key)
        }
    }