grammers_session/
session_data.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
9use std::collections::HashMap;
10
11use crate::defs::{DcOption, PeerId, PeerInfo, UpdateState, UpdatesState};
12use crate::{DEFAULT_DC, KNOWN_DC_OPTIONS, Session};
13
14/// In-memory representation of the entire [`Session`] state.
15///
16/// This type can be used for conversions `From` any [`Session`],
17/// and be [`SessionData::import_to`] any other [`Session`].
18pub struct SessionData {
19    /// The identifier of the datacenter option determined
20    /// to be the primary one for the logged-in user, or
21    /// the identifier of an arbitrary datacenter otherwise.
22    pub home_dc: i32,
23    /// List of all known datacenter options, along with their
24    /// Authorization Key if an encrypted connection has been
25    /// made to them previously. Indexed by their identifier.
26    pub dc_options: HashMap<i32, DcOption>,
27    /// List of all peer informations cached in the session.
28    /// Indexed by their identifier.
29    pub peer_infos: HashMap<PeerId, PeerInfo>,
30    /// Entirety of the update state for the logged-in user.
31    pub updates_state: UpdatesState,
32}
33
34impl Default for SessionData {
35    /// Constructs a default instance of the session data, with an arbitrary
36    /// [`Self::home_dc`] and the list of statically-known [`Self::dc_options`].
37    fn default() -> Self {
38        Self {
39            home_dc: DEFAULT_DC,
40            dc_options: KNOWN_DC_OPTIONS
41                .iter()
42                .cloned()
43                .map(|dc_option| (dc_option.id, dc_option))
44                .collect(),
45            peer_infos: HashMap::new(),
46            updates_state: UpdatesState::default(),
47        }
48    }
49}
50
51impl SessionData {
52    /// Imports all information from this session data to a type implementing `Session`.
53    pub fn import_to<S: Session>(&self, session: &S) {
54        session.set_home_dc_id(self.home_dc);
55        self.dc_options
56            .values()
57            .for_each(|dc_option| session.set_dc_option(dc_option));
58        self.peer_infos
59            .values()
60            .for_each(|peer| session.cache_peer(peer));
61        session.set_update_state(UpdateState::All(self.updates_state.clone()));
62    }
63}
64
65impl<S: Session> From<S> for SessionData {
66    /// Imports the basic information from any type implementing `Session` into `SessionData`.
67    ///
68    /// Notably, only the standard DC options and the cached self-peer will be included.
69    fn from(session: S) -> Self {
70        let home_dc = session.home_dc_id();
71        let dc_options = KNOWN_DC_OPTIONS
72            .iter()
73            .map(|dc_option| (dc_option.id, session.dc_option(dc_option.id).unwrap()))
74            .collect();
75        let peer_infos = [session
76            .peer(PeerId::self_user())
77            .map(|peer_info| (peer_info.id(), peer_info))]
78        .into_iter()
79        .collect::<Option<_>>()
80        .unwrap_or_default();
81        let updates_state = session.updates_state();
82
83        Self {
84            home_dc,
85            dc_options,
86            peer_infos,
87            updates_state,
88        }
89    }
90}