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}