grammers_client/types/
peer_map.rs

1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8use crate::types::{Peer, User};
9use grammers_session::defs::PeerId;
10use grammers_tl_types as tl;
11use std::collections::HashMap;
12use std::sync::Arc;
13
14/// Helper structure to efficiently retrieve peers via their peer.
15///
16/// A lot of responses include the peers related to them in the form of a list of users
17/// and peers, making it annoying to extract a specific peer. This structure lets you
18/// save those separate vectors in a single place and query them by using a `Peer`.
19pub struct PeerMap {
20    map: HashMap<PeerId, Peer>,
21}
22
23impl PeerMap {
24    /// Create a new peer set.
25    pub fn new<U, C>(users: U, peers: C) -> Arc<Self>
26    where
27        U: IntoIterator<Item = tl::enums::User>,
28        C: IntoIterator<Item = tl::enums::Chat>,
29    {
30        Arc::new(Self {
31            map: users
32                .into_iter()
33                .map(Peer::from_user)
34                .chain(peers.into_iter().map(Peer::from_raw))
35                .map(|peer| (peer.id(), peer))
36                .collect(),
37        })
38    }
39
40    /// Create a new empty peer set.
41    pub fn empty() -> Arc<Self> {
42        Arc::new(Self {
43            map: HashMap::new(),
44        })
45    }
46
47    /// Retrieve the full `Peer` object given its `PeerId`.
48    pub fn get(&self, peer: PeerId) -> Option<&Peer> {
49        self.map.get(&peer)
50    }
51
52    /// Take the full `Peer` object given its `PeerId` and remove it from the map.
53    pub fn remove(&mut self, peer: PeerId) -> Option<Peer> {
54        self.map.remove(&peer)
55    }
56
57    pub(crate) fn remove_user(&mut self, user_id: i64) -> Option<User> {
58        self.map
59            .remove(&PeerId::user(user_id))
60            .map(|peer| match peer {
61                Peer::User(user) => user,
62                _ => unreachable!(),
63            })
64    }
65
66    /// Iterate over the peers and peers in the map.
67    pub fn iter(&self) -> impl Iterator<Item = (PeerId, &Peer)> {
68        self.map.iter().map(|(k, v)| (*k, v))
69    }
70
71    /// Iterate over the peers in the map.
72    pub fn iter_peers(&self) -> impl Iterator<Item = &Peer> {
73        self.map.values()
74    }
75}