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: peer_addresses.rs
    path of file: ./repos/rust-libp2p/swarm/src/behaviour
    
    the code of the file until where you have to start completion: use crate::behaviour::FromSwarm;
use crate::{DialError, DialFailure, NewExternalAddrOfPeer};

use libp2p_core::Multiaddr;
use libp2p_identity::PeerId;

use lru::LruCache;

use std::num::NonZeroUsize;

/// Struct for tracking peers' external addresses of the [`Swarm`](crate::Swarm).
#[derive(Debug)]
pub struct PeerAddresses(LruCache<PeerId, LruCache<Multiaddr, ()>>);

impl PeerAddresses {
    /// Creates a [`PeerAddresses`] cache with capacity for the given number o
    
    fn addresses_of_peer_are_removed_when_received_dial_failure() {
        let mut cache = PeerAddresses::default();
        let peer_id = PeerId::random();

        let addr: Multiaddr = "/ip4/127.0.0.1/tcp/8080".parse().unwrap();
        let addr2: Multiaddr = "/ip4/127.0.0.1/tcp/8081".parse().unwrap();
        let addr3: Multiaddr = "/ip4/127.0.0.1/tcp/8082".parse().unwrap();

        cache.add(peer_id, addr.clone());
        cache.add(peer_id, addr2.clone());
        cache.add(peer_id, addr3.clone());

        let error = DialError::Transport(prepare_errors(vec![addr, addr3]));

        let event = FromSwarm::DialFailure(DialFailure {
            peer_id: Some(peer_id),
            error: &error,
            connection_id: ConnectionId::new_unchecked(8),
        });

        let changed = cache.on_swarm_event(&event);

        assert!(changed);

        let cached = cache.get(&peer_id).collect::<Vec<Multiaddr>>();
        let expected = prepare_expected_addrs(peer_id, [addr2].into_iter());

        assert_eq!(cached, expected);
    }