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/foundry/crates/linking/src
    
    the code of the file until where you have to start completion: #![cfg_attr(not(test), warn(unused_crate_dependencies))]

use alloy_primitives::{Address, Bytes};
use foundry_compilers::{
    artifacts::{CompactContractBytecode, Libraries},
    contracts::ArtifactContracts,
    Artifact, ArtifactId,
};
use semver::Version;
use std::{
    collections::BTreeSet,
    path::{Path, PathBuf},
    str::FromStr,
};

/// Errors that can occur during linking.
#[derive(Debug, thiserror::Error)]
pub enum LinkerError {
    #[error("wasn't able to find artifact for library {name} at {file}")]
    MissingLibraryArtifact { file: String, name: String },
    #[error("target artifact is not present in provided artifacts set")]
    MissingTargetArtifact,
    #[error(transparent)]
    InvalidAddress(<Address as std::str::FromStr>::Err),
}

pub struct Linker {
    /// Root of the project, used to determine whether artifact/library path can be stripped.
    pub root: PathBuf,
    /// Compilation artifacts.
    pub contracts: ArtifactContracts,
}

/// Output of the `link_with_nonce_or_address`
pub struct LinkOutput {
    /// Resolved library addresses. Contains both user-provided and newly deployed libraries.
    /// It will always contain library paths with stripped path prefixes.
    pub libraries: Libraries,
    /// Vector of libraries that need to be deployed from sender address.
    /// The order in which they appear in the vector is the order in which they should be deployed.
    pub libs_to_deploy: Vec<Bytes>,
}

impl Linker {
    pub fn new(root: impl Into<PathBuf>, contracts: ArtifactContract
    
        fn test_with_sender_and_nonce(self, sender: Address, initial_nonce: u64) {
            for id in self.linker.contracts.keys() {
                // If we didn't strip paths, artifacts will have absolute paths.
                // That's expected and we want to ensure that only `libraries` object has relative
                // paths, artifacts should be kept as is.
                let source = id
                    .source
                    .strip_prefix(self.project.root())
                    .unwrap_or(&id.source)
                    .to_string_lossy();
                let identifier = format!("{source}:{}", id.name);

                // Skip ds-test as it always has no dependencies etc. (and the path is outside root
                // so is not sanitized)
                if identifier.contains("DSTest") {
                    continue;
                }

                let LinkOutput { libs_to_deploy, libraries, .. } = self
                    .linker
                    .link_with_nonce_or_address(Default::default(), sender, initial_nonce, id)
                    .expect("Linking failed");

                let assertions = self
                    .dependency_assertions
                    .get(&identifier)
                    .unwrap_or_else(|| panic!("Unexpected artifact: {identifier}"));

                assert_eq!(
                    libs_to_deploy.len(),
                    assertions.len(),
                    "artifact {identifier} has more/less dependencies than expected ({} vs {}): {:#?}",
                    libs_to_deploy.len(),
                    assertions.len(),
                    libs_to_deploy
                );

                for (dep_identifier, address) in assertions {
                    let (file, name) = dep_identifier.split_once(':').unwrap();
                    if let Some(lib_address) =
                        libraries.libs.get(&PathBuf::from(file)).and_then(|libs| libs.get(name))
                    {
                        assert_eq!(*lib_address, address.to_string(), "incorrect library address for dependency {dep_identifier} of {identifier}");
                    } else {
                        panic!("Library not found")
                    }
                }
            }
        }