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}