From 16f031fabb7871fcd738b0f25391193ee4ca28a9 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sat, 27 Nov 2021 18:47:17 +0100 Subject: [PATCH] state-res: Make the API generic over the event ID storage --- .../ruma-state-res/benches/state_res_bench.rs | 48 +++--- crates/ruma-state-res/src/event_auth.rs | 6 +- crates/ruma-state-res/src/lib.rs | 137 +++++++++--------- crates/ruma-state-res/src/state_event.rs | 37 +++-- crates/ruma-state-res/src/test_utils.rs | 29 ++-- 5 files changed, 138 insertions(+), 119 deletions(-) diff --git a/crates/ruma-state-res/benches/state_res_bench.rs b/crates/ruma-state-res/benches/state_res_bench.rs index dbbefe63..1fc97e3e 100644 --- a/crates/ruma-state-res/benches/state_res_bench.rs +++ b/crates/ruma-state-res/benches/state_res_bench.rs @@ -8,6 +8,7 @@ #![allow(clippy::exhaustive_structs)] use std::{ + borrow::Borrow, collections::{HashMap, HashSet}, convert::TryInto, sync::{ @@ -182,11 +183,7 @@ impl TestStore { } /// Returns a Vec of the related auth events to the given `event`. - fn auth_event_ids( - &self, - room_id: &RoomId, - event_ids: Vec>, - ) -> Result>> { + fn auth_event_ids(&self, room_id: &RoomId, event_ids: Vec) -> Result> { let mut result = HashSet::new(); let mut stack = event_ids; @@ -199,7 +196,7 @@ impl TestStore { result.insert(ev_id.clone()); - let event = self.get_event(room_id, &ev_id)?; + let event = self.get_event(room_id, ev_id.borrow())?; stack.extend(event.auth_events().map(ToOwned::to_owned)); } @@ -207,13 +204,8 @@ impl TestStore { Ok(result) } - /// Returns a Vec> representing the difference in auth chains of the given - /// `events`. - fn auth_chain_diff( - &self, - room_id: &RoomId, - event_ids: Vec>>, - ) -> Result>> { + /// Returns a vector representing the difference in auth chains of the given `events`. + fn auth_chain_diff(&self, room_id: &RoomId, event_ids: Vec>) -> Result> { let mut auth_chain_sets = vec![]; for ids in event_ids { // TODO state store `auth_event_ids` returns self in the event ids list @@ -226,9 +218,13 @@ impl TestStore { let common = auth_chain_sets .iter() .skip(1) - .fold(first, |a, b| a.intersection(b).cloned().collect::>>()); + .fold(first, |a, b| a.intersection(b).cloned().collect::>()); - Ok(auth_chain_sets.into_iter().flatten().filter(|id| !common.contains(id)).collect()) + Ok(auth_chain_sets + .into_iter() + .flatten() + .filter(|id| !common.contains(id.borrow())) + .collect()) } else { Ok(vec![]) } @@ -546,7 +542,9 @@ mod event { use serde_json::value::RawValue as RawJsonValue; impl Event for StateEvent { - fn event_id(&self) -> &EventId { + type Id = Box; + + fn event_id(&self) -> &Self::Id { &self.event_id } @@ -604,28 +602,28 @@ mod event { } } - fn prev_events(&self) -> Box + '_> { + fn prev_events(&self) -> Box + '_> { match &self.rest { - Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| &**id)), - Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter().map(|id| &**id)), + Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| id)), + Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter()), #[cfg(not(feature = "unstable-exhaustive-types"))] _ => unreachable!("new PDU version"), } } - fn auth_events(&self) -> Box + '_> { + fn auth_events(&self) -> Box + '_> { match &self.rest { - Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| &**id)), - Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter().map(|id| &**id)), + Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| id)), + Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter()), #[cfg(not(feature = "unstable-exhaustive-types"))] _ => unreachable!("new PDU version"), } } - fn redacts(&self) -> Option<&EventId> { + fn redacts(&self) -> Option<&Self::Id> { match &self.rest { - Pdu::RoomV1Pdu(ev) => ev.redacts.as_deref(), - Pdu::RoomV3Pdu(ev) => ev.redacts.as_deref(), + Pdu::RoomV1Pdu(ev) => ev.redacts.as_ref(), + Pdu::RoomV3Pdu(ev) => ev.redacts.as_ref(), #[cfg(not(feature = "unstable-exhaustive-types"))] _ => unreachable!("new PDU version"), } diff --git a/crates/ruma-state-res/src/event_auth.rs b/crates/ruma-state-res/src/event_auth.rs index cb8429a4..981649f6 100644 --- a/crates/ruma-state-res/src/event_auth.rs +++ b/crates/ruma-state-res/src/event_auth.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeSet, convert::TryFrom}; +use std::{borrow::Borrow, collections::BTreeSet, convert::TryFrom}; use js_int::{int, Int}; use ruma_events::{ @@ -749,8 +749,8 @@ fn check_redaction( // If the domain of the event_id of the event being redacted is the same as the // domain of the event_id of the m.room.redaction, allow - if redaction_event.event_id().server_name() - == redaction_event.redacts().as_ref().and_then(|id| id.server_name()) + if redaction_event.event_id().borrow().server_name() + == redaction_event.redacts().as_ref().and_then(|&id| id.borrow().server_name()) { info!("redaction event allowed via room version 1 rules"); return Ok(true); diff --git a/crates/ruma-state-res/src/lib.rs b/crates/ruma-state-res/src/lib.rs index dab1e09f..5e072f03 100644 --- a/crates/ruma-state-res/src/lib.rs +++ b/crates/ruma-state-res/src/lib.rs @@ -1,6 +1,8 @@ use std::{ + borrow::Borrow, cmp::Reverse, collections::{BTreeMap, BinaryHeap, HashMap, HashSet}, + hash::Hash, }; use itertools::Itertools; @@ -53,12 +55,13 @@ pub type StateMap = HashMap<(EventType, String), T>; pub fn resolve<'a, E, SetIter>( room_version: &RoomVersionId, state_sets: impl IntoIterator, - auth_chain_sets: Vec>>, + auth_chain_sets: Vec>, fetch_event: impl Fn(&EventId) -> Option, -) -> Result>> +) -> Result> where E: Event + Clone, - SetIter: Iterator>> + Clone, + E::Id: 'a, + SetIter: Iterator> + Clone, { info!("State resolution starting"); @@ -82,7 +85,7 @@ where // FIXME: Use into_values() once MSRV >= 1.54 .chain(conflicting.into_iter().flat_map(|(_k, v)| v)) // Don't honor events we cannot "verify" - .filter(|id| fetch_event(id).is_some()) + .filter(|id| fetch_event(id.borrow()).is_some()) .collect(); info!("full conflicted set: {}", all_conflicted.len()); @@ -94,7 +97,7 @@ where // Get only the control events with a state_key: "" or ban/kick event (sender != state_key) let control_events = all_conflicted .iter() - .filter(|id| is_power_event_id(id, &fetch_event)) + .filter(|&id| is_power_event_id(id.borrow(), &fetch_event)) .cloned() .collect::>(); @@ -121,7 +124,7 @@ where // auth let events_to_resolve = all_conflicted .iter() - .filter(|&id| !deduped_power_ev.contains(id)) + .filter(|&id| !deduped_power_ev.contains(id.borrow())) .cloned() .collect::>(); @@ -133,8 +136,7 @@ where debug!("power event: {:?}", power_event); - let sorted_left_events = - mainline_sort(&events_to_resolve, power_event.map(|id| &**id), &fetch_event)?; + let sorted_left_events = mainline_sort(&events_to_resolve, power_event.cloned(), &fetch_event)?; trace!("events left, sorted: {:?}", sorted_left_events); @@ -158,9 +160,12 @@ where /// State is determined to be conflicting if for the given key (EventType, StateKey) there is not /// exactly one eventId. This includes missing events, if one state_set includes an event that none /// of the other have this is a conflicting event. -fn separate<'a>( - state_sets_iter: impl Iterator>> + Clone, -) -> (StateMap>, StateMap>>) { +fn separate<'a, Id>( + state_sets_iter: impl Iterator> + Clone, +) -> (StateMap, StateMap>) +where + Id: Clone + Eq + 'a, +{ let mut unconflicted_state = StateMap::new(); let mut conflicted_state = StateMap::new(); @@ -184,12 +189,13 @@ fn separate<'a>( } /// Returns a Vec of deduped EventIds that appear in some chains but not others. -fn get_auth_chain_diff( - auth_chain_sets: Vec>>, -) -> impl Iterator> { +fn get_auth_chain_diff(auth_chain_sets: Vec>) -> impl Iterator +where + Id: Eq + Hash, +{ let num_sets = auth_chain_sets.len(); - let mut id_counts: HashMap, usize> = HashMap::new(); + let mut id_counts: HashMap = HashMap::new(); for id in auth_chain_sets.into_iter().flatten() { *id_counts.entry(id).or_default() += 1; } @@ -205,10 +211,10 @@ fn get_auth_chain_diff( /// The power level is negative because a higher power level is equated to an earlier (further back /// in time) origin server timestamp. fn reverse_topological_power_sort( - events_to_sort: Vec>, - auth_diff: &HashSet>, + events_to_sort: Vec, + auth_diff: &HashSet, fetch_event: impl Fn(&EventId) -> Option, -) -> Result>> { +) -> Result> { debug!("reverse topological sort of power events"); let mut graph = HashMap::new(); @@ -223,7 +229,7 @@ fn reverse_topological_power_sort( // This is used in the `key_fn` passed to the lexico_topo_sort fn let mut event_to_pl = HashMap::new(); for event_id in graph.keys() { - let pl = get_power_level_for_sender(event_id, &fetch_event)?; + let pl = get_power_level_for_sender(event_id.borrow(), &fetch_event)?; info!("{} power level {}", event_id, pl); event_to_pl.insert(event_id.clone(), pl); @@ -244,18 +250,19 @@ fn reverse_topological_power_sort( /// /// `key_fn` is used as to obtain the power level and age of an event for breaking ties (together /// with the event ID). -pub fn lexicographical_topological_sort( - graph: &HashMap, HashSet>>, +pub fn lexicographical_topological_sort( + graph: &HashMap>, key_fn: F, -) -> Result>> +) -> Result> where F: Fn(&EventId) -> Result<(Int, MilliSecondsSinceUnixEpoch)>, + Id: Clone + Eq + Ord + Hash + Borrow, { #[derive(PartialEq, Eq, PartialOrd, Ord)] - struct TieBreaker<'a> { + struct TieBreaker<'a, Id> { inv_power_level: Int, age: MilliSecondsSinceUnixEpoch, - event_id: &'a EventId, + event_id: &'a Id, } info!("starting lexicographical topological sort"); @@ -272,14 +279,14 @@ where // The number of events that depend on the given event (the EventId key) // How many events reference this event in the DAG as a parent - let mut reverse_graph: HashMap<&EventId, HashSet<&EventId>> = HashMap::new(); + let mut reverse_graph: HashMap<_, HashSet<_>> = HashMap::new(); // Vec of nodes that have zero out degree, least recent events. - let mut zero_outdegree: Vec>> = vec![]; + let mut zero_outdegree = Vec::new(); for (node, edges) in graph { if edges.is_empty() { - let (power_level, age) = key_fn(node)?; + let (power_level, age) = key_fn(node.borrow())?; // The `Reverse` is because rusts `BinaryHeap` sorts largest -> smallest we need // smallest -> largest zero_outdegree.push(Reverse(TieBreaker { @@ -306,13 +313,13 @@ where for &parent in reverse_graph.get(node).expect("EventId in heap is also in reverse_graph") { // The number of outgoing edges this node has let out = outdegree_map - .get_mut(parent) + .get_mut(parent.borrow()) .expect("outdegree_map knows of all referenced EventIds"); // Only push on the heap once older events have been cleared - out.remove(node); + out.remove(node.borrow()); if out.is_empty() { - let (power_level, age) = key_fn(node)?; + let (power_level, age) = key_fn(node.borrow())?; heap.push(Reverse(TieBreaker { inv_power_level: -power_level, age, @@ -322,7 +329,7 @@ where } // synapse yields we push then return the vec - sorted.push(node.to_owned()); + sorted.push(node.clone()); } Ok(sorted) @@ -357,7 +364,7 @@ fn get_power_level_for_sender( let mut pl = None; for aid in event.as_ref().map(|pdu| pdu.auth_events()).into_iter().flatten() { - if let Some(aev) = fetch_event(aid) { + if let Some(aev) = fetch_event(aid.borrow()) { if is_type_and_key(&aev, &EventType::RoomPowerLevels, "") { pl = Some(aev); break; @@ -385,16 +392,16 @@ fn get_power_level_for_sender( /// ## Returns /// /// The `unconflicted_state` combined with the newly auth'ed events. So any event that fails the -/// `event_auth::auth_check` will be excluded from the returned `StateMap>`. +/// `event_auth::auth_check` will be excluded from the returned state map. /// /// For each `events_to_check` event we gather the events needed to auth it from the the /// `fetch_event` closure and verify each event using the `event_auth::auth_check` function. fn iterative_auth_check( room_version: &RoomVersion, - events_to_check: &[Box], - unconflicted_state: StateMap>, + events_to_check: &[E::Id], + unconflicted_state: StateMap, fetch_event: impl Fn(&EventId) -> Option, -) -> Result>> { +) -> Result> { info!("starting iterative auth check"); debug!("performing auth checks on {:?}", events_to_check); @@ -402,7 +409,7 @@ fn iterative_auth_check( let mut resolved_state = unconflicted_state; for event_id in events_to_check { - let event = fetch_event(event_id) + let event = fetch_event(event_id.borrow()) .ok_or_else(|| Error::NotFound(format!("Failed to find {}", event_id)))?; let state_key = event .state_key() @@ -410,7 +417,7 @@ fn iterative_auth_check( let mut auth_events = HashMap::new(); for aid in event.auth_events() { - if let Some(ev) = fetch_event(aid) { + if let Some(ev) = fetch_event(aid.borrow()) { // TODO synapse check "rejected_reason" which is most likely // related to soft-failing auth_events.insert( @@ -436,7 +443,7 @@ fn iterative_auth_check( event.content(), )? { if let Some(ev_id) = resolved_state.get(&key) { - if let Some(event) = fetch_event(ev_id) { + if let Some(event) = fetch_event(ev_id.borrow()) { // TODO synapse checks `rejected_reason` is None here auth_events.insert(key.to_owned(), event); } @@ -447,7 +454,7 @@ fn iterative_auth_check( #[allow(clippy::redundant_closure)] let most_recent_prev_event = - event.prev_events().filter_map(|id| fetch_event(id)).next_back(); + event.prev_events().filter_map(|id| fetch_event(id.borrow())).next_back(); // The key for this is (eventType + a state_key of the signed token not sender) so // search for it @@ -488,10 +495,10 @@ fn iterative_auth_check( /// the events before (with the first power level as a parent) will be marked as depth 1. depth 1 is /// "older" than depth 0. fn mainline_sort( - to_sort: &[Box], - resolved_power_level: Option<&EventId>, + to_sort: &[E::Id], + resolved_power_level: Option, fetch_event: impl Fn(&EventId) -> Option, -) -> Result>> { +) -> Result> { debug!("mainline sort of events"); // There are no EventId's to sort, bail. @@ -500,15 +507,15 @@ fn mainline_sort( } let mut mainline = vec![]; - let mut pl = resolved_power_level.map(ToOwned::to_owned); + let mut pl = resolved_power_level; while let Some(p) = pl { mainline.push(p.clone()); - let event = - fetch_event(&p).ok_or_else(|| Error::NotFound(format!("Failed to find {}", p)))?; + let event = fetch_event(p.borrow()) + .ok_or_else(|| Error::NotFound(format!("Failed to find {}", p)))?; pl = None; for aid in event.auth_events() { - let ev = fetch_event(aid) + let ev = fetch_event(aid.borrow()) .ok_or_else(|| Error::NotFound(format!("Failed to find {}", aid)))?; if is_type_and_key(&ev, &EventType::RoomPowerLevels, "") { pl = Some(aid.to_owned()); @@ -529,11 +536,11 @@ fn mainline_sort( let mut order_map = HashMap::new(); for ev_id in to_sort.iter() { - if let Some(event) = fetch_event(ev_id) { + if let Some(event) = fetch_event(ev_id.borrow()) { if let Ok(depth) = get_mainline_depth(Some(event), &mainline_map, &fetch_event) { order_map.insert( ev_id, - (depth, fetch_event(ev_id).map(|ev| ev.origin_server_ts()), ev_id), + (depth, fetch_event(ev_id.borrow()).map(|ev| ev.origin_server_ts()), ev_id), ); } } @@ -555,19 +562,19 @@ fn mainline_sort( /// associated mainline depth. fn get_mainline_depth( mut event: Option, - mainline_map: &HashMap, usize>, + mainline_map: &HashMap, fetch_event: impl Fn(&EventId) -> Option, ) -> Result { while let Some(sort_ev) = event { debug!("mainline event_id {}", sort_ev.event_id()); let id = sort_ev.event_id(); - if let Some(depth) = mainline_map.get(id) { + if let Some(depth) = mainline_map.get(id.borrow()) { return Ok(*depth); } event = None; for aid in sort_ev.auth_events() { - let aev = fetch_event(aid) + let aev = fetch_event(aid.borrow()) .ok_or_else(|| Error::NotFound(format!("Failed to find {}", aid)))?; if is_type_and_key(&aev, &EventType::RoomPowerLevels, "") { event = Some(aev); @@ -580,23 +587,25 @@ fn get_mainline_depth( } fn add_event_and_auth_chain_to_graph( - graph: &mut HashMap, HashSet>>, - event_id: Box, - auth_diff: &HashSet>, + graph: &mut HashMap>, + event_id: E::Id, + auth_diff: &HashSet, fetch_event: impl Fn(&EventId) -> Option, ) { let mut state = vec![event_id]; while let Some(eid) = state.pop() { graph.entry(eid.clone()).or_default(); // Prefer the store to event as the store filters dedups the events - for aid in fetch_event(&eid).as_ref().map(|ev| ev.auth_events()).into_iter().flatten() { - if auth_diff.contains(aid) { - if !graph.contains_key(aid) { + for aid in + fetch_event(eid.borrow()).as_ref().map(|ev| ev.auth_events()).into_iter().flatten() + { + if auth_diff.contains(aid.borrow()) { + if !graph.contains_key(aid.borrow()) { state.push(aid.to_owned()); } // We just inserted this at the start of the while loop - graph.get_mut(&eid).unwrap().insert(aid.to_owned()); + graph.get_mut(eid.borrow()).unwrap().insert(aid.to_owned()); } } } @@ -672,7 +681,7 @@ mod tests { }) .collect::>(); - let auth_chain = HashSet::new(); + let auth_chain: HashSet> = HashSet::new(); let power_events = event_map .values() @@ -699,13 +708,11 @@ mod tests { events_to_sort.shuffle(&mut rand::thread_rng()); - let power_level = resolved_power.get(&(EventType::RoomPowerLevels, "".to_owned())); + let power_level = resolved_power.get(&(EventType::RoomPowerLevels, "".to_owned())).cloned(); let sorted_event_ids = - crate::mainline_sort(&events_to_sort, power_level.map(|id| &**id), |id| { - events.get(id).map(Arc::clone) - }) - .unwrap(); + crate::mainline_sort(&events_to_sort, power_level, |id| events.get(id).map(Arc::clone)) + .unwrap(); assert_eq!( vec![ diff --git a/crates/ruma-state-res/src/state_event.rs b/crates/ruma-state-res/src/state_event.rs index 8a039594..3512d549 100644 --- a/crates/ruma-state-res/src/state_event.rs +++ b/crates/ruma-state-res/src/state_event.rs @@ -1,4 +1,9 @@ -use std::sync::Arc; +use std::{ + borrow::Borrow, + fmt::{Debug, Display}, + hash::Hash, + sync::Arc, +}; use ruma_common::MilliSecondsSinceUnixEpoch; use ruma_events::EventType; @@ -7,8 +12,10 @@ use serde_json::value::RawValue as RawJsonValue; /// Abstraction of a PDU so users can have their own PDU types. pub trait Event { + type Id: Clone + Debug + Display + Eq + Ord + Hash + Borrow; + /// The `EventId` of this event. - fn event_id(&self) -> &EventId; + fn event_id(&self) -> &Self::Id; /// The `RoomId` of this event. fn room_id(&self) -> &RoomId; @@ -30,18 +37,20 @@ pub trait Event { /// The events before this event. // Requires GATs to avoid boxing (and TAIT for making it convenient). - fn prev_events(&self) -> Box + '_>; + fn prev_events(&self) -> Box + '_>; /// All the authenticating events for this event. // Requires GATs to avoid boxing (and TAIT for making it convenient). - fn auth_events(&self) -> Box + '_>; + fn auth_events(&self) -> Box + '_>; /// If this event is a redaction event this is the event it redacts. - fn redacts(&self) -> Option<&EventId>; + fn redacts(&self) -> Option<&Self::Id>; } impl Event for &T { - fn event_id(&self) -> &EventId { + type Id = T::Id; + + fn event_id(&self) -> &Self::Id { (*self).event_id() } @@ -69,21 +78,23 @@ impl Event for &T { (*self).state_key() } - fn prev_events(&self) -> Box + '_> { + fn prev_events(&self) -> Box + '_> { (*self).prev_events() } - fn auth_events(&self) -> Box + '_> { + fn auth_events(&self) -> Box + '_> { (*self).auth_events() } - fn redacts(&self) -> Option<&EventId> { + fn redacts(&self) -> Option<&Self::Id> { (*self).redacts() } } impl Event for Arc { - fn event_id(&self) -> &EventId { + type Id = T::Id; + + fn event_id(&self) -> &Self::Id { (&**self).event_id() } @@ -111,15 +122,15 @@ impl Event for Arc { (&**self).state_key() } - fn prev_events(&self) -> Box + '_> { + fn prev_events(&self) -> Box + '_> { (&**self).prev_events() } - fn auth_events(&self) -> Box + '_> { + fn auth_events(&self) -> Box + '_> { (&**self).auth_events() } - fn redacts(&self) -> Option<&EventId> { + fn redacts(&self) -> Option<&Self::Id> { (&**self).redacts() } } diff --git a/crates/ruma-state-res/src/test_utils.rs b/crates/ruma-state-res/src/test_utils.rs index 728e110b..0fd08e9c 100644 --- a/crates/ruma-state-res/src/test_utils.rs +++ b/crates/ruma-state-res/src/test_utils.rs @@ -1,4 +1,5 @@ use std::{ + borrow::Borrow, collections::{BTreeMap, HashMap, HashSet}, convert::TryInto, sync::{ @@ -218,8 +219,8 @@ impl TestStore { pub fn auth_event_ids( &self, room_id: &RoomId, - event_ids: Vec>, - ) -> Result>> { + event_ids: Vec, + ) -> Result> { let mut result = HashSet::new(); let mut stack = event_ids; @@ -231,7 +232,7 @@ impl TestStore { result.insert(ev_id.clone()); - let event = self.get_event(room_id, &ev_id)?; + let event = self.get_event(room_id, ev_id.borrow())?; stack.extend(event.auth_events().map(ToOwned::to_owned)); } @@ -550,7 +551,9 @@ pub mod event { use crate::Event; impl Event for StateEvent { - fn event_id(&self) -> &EventId { + type Id = Box; + + fn event_id(&self) -> &Self::Id { &self.event_id } @@ -608,28 +611,28 @@ pub mod event { } } - fn prev_events(&self) -> Box + '_> { + fn prev_events(&self) -> Box + '_> { match &self.rest { - Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| &**id)), - Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter().map(|id| &**id)), + Pdu::RoomV1Pdu(ev) => Box::new(ev.prev_events.iter().map(|(id, _)| id)), + Pdu::RoomV3Pdu(ev) => Box::new(ev.prev_events.iter()), #[allow(unreachable_patterns)] _ => unreachable!("new PDU version"), } } - fn auth_events(&self) -> Box + '_> { + fn auth_events(&self) -> Box + '_> { match &self.rest { - Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| &**id)), - Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter().map(|id| &**id)), + Pdu::RoomV1Pdu(ev) => Box::new(ev.auth_events.iter().map(|(id, _)| id)), + Pdu::RoomV3Pdu(ev) => Box::new(ev.auth_events.iter()), #[allow(unreachable_patterns)] _ => unreachable!("new PDU version"), } } - fn redacts(&self) -> Option<&EventId> { + fn redacts(&self) -> Option<&Self::Id> { match &self.rest { - Pdu::RoomV1Pdu(ev) => ev.redacts.as_deref(), - Pdu::RoomV3Pdu(ev) => ev.redacts.as_deref(), + Pdu::RoomV1Pdu(ev) => ev.redacts.as_ref(), + Pdu::RoomV3Pdu(ev) => ev.redacts.as_ref(), #[allow(unreachable_patterns)] _ => unreachable!("new PDU version"), }