realtime_rs/message/
presence.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// Enum of presence event types
7#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
8#[serde(rename_all = "snake_case")]
9pub enum PresenceEvent {
10    Track,
11    Untrack,
12    Join,
13    Leave,
14    Sync,
15}
16
17pub type RawPresenceState = HashMap<String, RawPresenceMetas>;
18
19//{
20//  abc123: {1: {foo: bar}, 2: {foo: baz} },
21//  def456: {3: {foo: baz}, 4: {foo: bar} },
22//}
23//
24// triple nested hashmap, fantastic. gonna need to write some helper functions for this one
25pub type PresenceStateInner = HashMap<String, PhxMap>;
26
27pub type PhxMap = HashMap<String, StateData>;
28
29pub type StateData = HashMap<String, Value>;
30
31/// PresenceState triple nested hashmap.
32///
33/// Layout:
34/// HashMap<id, HashMap<phx_ref, HashMap<key, value>>>
35/// { \[id\]: { \[ref\]: { \[key\]: value } } }
36#[derive(Default, Clone, Debug)]
37pub struct PresenceState(pub PresenceStateInner);
38
39impl PresenceState {
40    /// Returns a once flattened map of presence data:
41    /// HashMap<phx_ref, Hashmap<key, value>>
42    pub fn get_phx_map(&self) -> PhxMap {
43        let mut new_map = HashMap::new();
44        for (_id, map) in self.0.clone() {
45            for (phx_id, state_data) in map {
46                new_map.insert(phx_id, state_data);
47            }
48        }
49        new_map
50    }
51}
52
53type PresenceIteratorItem = (String, HashMap<String, HashMap<String, Value>>);
54
55impl FromIterator<PresenceIteratorItem> for PresenceState {
56    fn from_iter<T: IntoIterator<Item = PresenceIteratorItem>>(iter: T) -> Self {
57        let mut new_id_map = HashMap::new();
58
59        for (id, id_map) in iter {
60            new_id_map.insert(id, id_map);
61        }
62
63        PresenceState(new_id_map)
64    }
65}
66
67/// Raw presence meta data
68#[derive(Serialize, Deserialize, Debug, Clone, Default)]
69pub struct RawPresenceMeta {
70    pub phx_ref: String,
71    #[serde(flatten)]
72    pub state_data: HashMap<String, Value>,
73}
74
75/// Collection of raw presence metas
76#[derive(Serialize, Deserialize, Debug, Clone, Default)]
77pub struct RawPresenceMetas {
78    pub metas: Vec<RawPresenceMeta>,
79}
80
81impl From<RawPresenceState> for PresenceState {
82    fn from(val: RawPresenceState) -> Self {
83        let mut transformed_state = PresenceState(HashMap::new());
84
85        for (id, metas) in val {
86            let mut transformed_inner = HashMap::new();
87
88            for meta in metas.metas {
89                transformed_inner.insert(meta.phx_ref, meta.state_data);
90            }
91
92            transformed_state.0.insert(id, transformed_inner);
93        }
94
95        transformed_state
96    }
97}
98
99/// Internal, visibility skill issues mean still visible to crate consumer TODO
100#[derive(Serialize, Deserialize, Debug, Clone)]
101pub struct RawPresenceDiff {
102    joins: RawPresenceState,
103    leaves: RawPresenceState,
104}
105
106impl From<RawPresenceDiff> for PresenceDiff {
107    fn from(val: RawPresenceDiff) -> Self {
108        PresenceDiff {
109            joins: val.joins.into(),
110            leaves: val.leaves.into(),
111        }
112    }
113}
114
115#[derive(Debug, Clone)]
116pub(crate) struct PresenceDiff {
117    pub joins: PresenceState,
118    pub leaves: PresenceState,
119}