tuwunel_matrix/room/state/resolution/test_utils/
fetch.rs1use std::{collections::HashMap, future::ready, hash::BuildHasher};
2
3use ruma::{EventId, OwnedEventId, events::StateEventType};
4use serde::Deserialize;
5use tuwunel_core::Result;
6
7#[cfg(test)]
8use super::TestStateMap;
9use super::{
10 super::{FetchEvent, FetchState},
11 event_not_found,
12};
13use crate::{PduEvent, StateKey};
14
15impl<F, Fut> FetchEvent for &F
16where
17 F: Fn(OwnedEventId) -> Fut + Sync,
18 Fut: Future<Output = Result<PduEvent>> + Send,
19{
20 async fn get<T>(self, event_id: &EventId) -> Result<T>
21 where
22 T: for<'de> Deserialize<'de> + Send,
23 {
24 let event = self(event_id.to_owned()).await?;
25
26 project(&event)
27 }
28
29 async fn exists(self, event_id: &EventId) -> Result<bool> {
30 match self(event_id.to_owned()).await {
31 | Ok(_) => Ok(true),
32 | Err(error) if error.is_not_found() => Ok(false),
33 | Err(error) => Err(error),
34 }
35 }
36}
37
38impl<E, X, EFut, XFut> FetchEvent for (&E, &X)
39where
40 E: Fn(OwnedEventId) -> EFut + Sync,
41 X: Fn(OwnedEventId) -> XFut + Sync,
42 EFut: Future<Output = Result<PduEvent>> + Send,
43 XFut: Future<Output = Result<bool>> + Send,
44{
45 fn get<T>(self, event_id: &EventId) -> impl Future<Output = Result<T>> + Send
46 where
47 T: for<'de> Deserialize<'de> + Send,
48 {
49 FetchEvent::get(self.0, event_id)
50 }
51
52 fn exists(self, event_id: &EventId) -> impl Future<Output = Result<bool>> + Send {
53 self.1(event_id.to_owned())
54 }
55}
56
57impl<S: BuildHasher + Sync> FetchEvent for &HashMap<OwnedEventId, PduEvent, S> {
58 fn get<T>(self, event_id: &EventId) -> impl Future<Output = Result<T>> + Send
59 where
60 T: for<'de> Deserialize<'de> + Send,
61 {
62 ready(
63 HashMap::get(self, event_id)
64 .ok_or_else(|| event_not_found(event_id))
65 .and_then(project),
66 )
67 }
68
69 fn exists(self, event_id: &EventId) -> impl Future<Output = Result<bool>> + Send {
70 ready(Ok(self.contains_key(event_id)))
71 }
72}
73
74impl<S: BuildHasher + Sync> FetchEvent for &HashMap<OwnedEventId, Vec<u8>, S> {
75 fn get<T>(self, event_id: &EventId) -> impl Future<Output = Result<T>> + Send
76 where
77 T: for<'de> Deserialize<'de> + Send,
78 {
79 ready(
80 HashMap::get(self, event_id)
81 .ok_or_else(|| event_not_found(event_id))
82 .and_then(|row| serde_json::from_slice(row).map_err(Into::into)),
83 )
84 }
85
86 fn exists(self, event_id: &EventId) -> impl Future<Output = Result<bool>> + Send {
87 ready(Ok(self.contains_key(event_id)))
88 }
89}
90
91impl<F, Fut> FetchState for &F
92where
93 F: Fn(StateEventType, StateKey) -> Fut + Sync,
94 Fut: Future<Output = Result<PduEvent>> + Send,
95{
96 type Pdu = PduEvent;
97
98 fn get(
99 self,
100 event_type: StateEventType,
101 state_key: StateKey,
102 ) -> impl Future<Output = Result<Self::Pdu>> + Send {
103 self(event_type, state_key)
104 }
105}
106
107#[cfg(test)]
108impl<'a> FetchState for &'a TestStateMap {
109 type Pdu = &'a PduEvent;
110
111 fn get(
112 self,
113 event_type: StateEventType,
114 state_key: StateKey,
115 ) -> impl Future<Output = Result<Self::Pdu>> + Send {
116 ready(TestStateMap::get(self, &event_type, state_key.as_str()))
117 }
118}
119
120fn project<T: for<'de> Deserialize<'de>>(event: &PduEvent) -> Result<T> {
121 let row = serde_json::to_vec(event)?;
122
123 serde_json::from_slice(&row).map_err(Into::into)
124}