atagen

macltok

public
Star0
Watch0
9c05b1dd327a57081652545c709cc8d7e961de15
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
src/engine/prepare.rsRust47 lines1.6 KB
1
use std::collections::HashMap;
2
3
use futures_util::{
4
    FutureExt,
5
    future::{Shared, WeakShared},
6
};
7
use matrix_sdk::Client;
8
use ruma::OwnedRoomId;
9
10
use super::executor::EngineBoxFuture;
11
use crate::Error;
12
13
type Flight = Shared<EngineBoxFuture<'static, Result<(), Error>>>;
14
15
/// one warm-up per room at a time, later asks join the one in flight
16
#[derive(Default)]
17
pub(super) struct Preparations(
18
    HashMap<OwnedRoomId, WeakShared<EngineBoxFuture<'static, Result<(), Error>>>>,
19
);
20
21
impl Preparations {
22
    pub(super) fn join(&mut self, client: &Client, room_id: OwnedRoomId) -> Flight {
23
        self.0.retain(|_, flight| flight.upgrade().is_some());
24
        if let Some(flight) = self.0.get(&room_id).and_then(WeakShared::upgrade) {
25
            return flight;
26
        }
27
        let work: EngineBoxFuture<'static, _> = Box::pin(prepare(client.clone(), room_id.clone()));
28
        let flight = work.shared();
29
        if let Some(weak) = flight.downgrade() {
30
            self.0.insert(room_id, weak);
31
        }
32
        flight
33
    }
34
}
35
36
/// the part of the sdk's pre-send encryption work it lets us reach. syncing the members
37
/// has the sdk track them all, and its own background `/keys/query` then catches up
38
/// their devices. the one time key claim and the room key share stay on the send path
39
async fn prepare(client: Client, room_id: OwnedRoomId) -> Result<(), Error> {
40
    let room = client.get_room(&room_id).ok_or_else(Error::room_unknown)?;
41
    if room.encryption_state().is_encrypted() && !room.are_members_synced() {
42
        room.sync_members()
43
            .await
44
            .map_err(|source| Error::from_sdk("syncing room members failed", source))?;
45
    }
46
    Ok(())
47
}