grammers_session/chat/
hash_cache.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.
8
9#![allow(deprecated)]
10use grammers_tl_types as tl;
11use std::collections::HashMap;
12
13use crate::defs::{PeerAuth, PeerId, PeerInfo, PeerRef};
14
15/// In-memory chat cache, mapping peers to their respective access hashes.
16#[deprecated(note = "Use the Session::peer instead")]
17pub struct PeerAuthCache {
18    hash_map: HashMap<PeerId, PeerAuth>,
19    self_id: Option<i64>,
20    self_bot: bool,
21}
22
23impl PeerAuthCache {
24    pub fn new(self_user: Option<(i64, bool)>) -> Self {
25        Self {
26            hash_map: HashMap::new(),
27            self_id: self_user.map(|user| user.0),
28            self_bot: self_user.map(|user| user.1).unwrap_or(false),
29        }
30    }
31
32    pub fn self_id(&self) -> i64 {
33        self.self_id
34            .expect("tried to query self_id before it's known")
35    }
36
37    pub fn is_self_bot(&self) -> bool {
38        self.self_bot
39    }
40
41    pub fn set_self_user(&mut self, user: PeerInfo) {
42        match user {
43            PeerInfo::User { id, bot, .. } => {
44                self.self_bot = bot.unwrap_or_default();
45                self.self_id = Some(id);
46            }
47            _ => panic!("tried to set self-user without providing user type"),
48        }
49    }
50
51    pub fn get(&self, id: PeerId) -> Option<PeerRef> {
52        self.hash_map.get(&id).map(|&auth| PeerRef { id, auth })
53    }
54
55    // Returns `true` if all users and chats could be extended without issue.
56    // Returns `false` if there is any user or chat for which its `access_hash` is missing.
57    #[must_use]
58    pub fn extend(&mut self, users: &[tl::enums::User], chats: &[tl::enums::Chat]) -> bool {
59        // See https://core.telegram.org/api/min for "issues" with "min constructors".
60        use tl::enums::{Chat as C, User as U};
61
62        let mut success = true;
63
64        users.iter().for_each(|user| match user {
65            U::Empty(_) => {}
66            U::User(u) => match (u.min, u.access_hash) {
67                (false, Some(hash)) => {
68                    self.hash_map
69                        .insert(PeerId::user(u.id), PeerAuth::from_hash(hash));
70                }
71                _ => success &= self.hash_map.contains_key(&PeerId::user(u.id)),
72            },
73        });
74
75        chats.iter().for_each(|chat| match chat {
76            C::Empty(_) | C::Chat(_) | C::Forbidden(_) => {}
77            C::Channel(c) => match (c.min, c.access_hash) {
78                (false, Some(hash)) => {
79                    self.hash_map
80                        .insert(PeerId::channel(c.id), PeerAuth::from_hash(hash));
81                }
82                _ => success &= self.hash_map.contains_key(&PeerId::channel(c.id)),
83            },
84            C::ChannelForbidden(c) => {
85                self.hash_map
86                    .insert(PeerId::channel(c.id), PeerAuth::from_hash(c.access_hash));
87            }
88        });
89
90        success
91    }
92}