Skip to main content

tuwunel_matrix/room/state/resolution/test_utils/
fetch.rs

1use 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}