1414
1515use std:: cmp:: Ordering ;
1616
17+ use eyeball_im:: VectorDiff ;
1718pub use matrix_sdk_base:: event_cache:: { Event , Gap } ;
19+ use matrix_sdk_base:: linked_chunk:: AsVector ;
1820use matrix_sdk_common:: linked_chunk:: {
1921 Chunk , ChunkIdentifier , EmptyChunk , Error , Iter , LinkedChunk , Position ,
2022} ;
@@ -31,6 +33,11 @@ pub struct RoomEvents {
3133 /// The real in-memory storage for all the events.
3234 chunks : LinkedChunk < DEFAULT_CHUNK_CAPACITY , Event , Gap > ,
3335
36+ /// Type mapping [`Update`]s from [`Self::chunks`] to [`VectorDiff`]s.
37+ ///
38+ /// [`Update`]: matrix_sdk_base::linked_chunk::Update
39+ chunks_updates_as_vectordiffs : AsVector < Event , Gap > ,
40+
3441 /// The events deduplicator instance to help finding duplicates.
3542 deduplicator : Deduplicator ,
3643}
@@ -44,12 +51,22 @@ impl Default for RoomEvents {
4451impl RoomEvents {
4552 /// Build a new [`RoomEvents`] struct with zero events.
4653 pub fn new ( ) -> Self {
47- Self { chunks : LinkedChunk :: new ( ) , deduplicator : Deduplicator :: new ( ) }
54+ let mut chunks = LinkedChunk :: new_with_update_history ( ) ;
55+ let chunks_updates_as_vectordiffs = chunks
56+ . as_vector ( )
57+ // SAFETY: The `LinkedChunk` has been built with `new_with_update_history`, so
58+ // `as_vector` must return `Some(…)`.
59+ . expect ( "`LinkedChunk` must have been constructor with `new_with_update_history`" ) ;
60+
61+ Self { chunks, chunks_updates_as_vectordiffs, deduplicator : Deduplicator :: new ( ) }
4862 }
4963
5064 /// Clear all events.
65+ ///
66+ /// All events, all gaps, everything is dropped, move into the void, into
67+ /// the ether, forever.
5168 pub fn reset ( & mut self ) {
52- self . chunks = LinkedChunk :: new ( ) ;
69+ self . chunks . clear ( ) ;
5370 }
5471
5572 /// Push events after all events or gaps.
@@ -158,6 +175,18 @@ impl RoomEvents {
158175 self . chunks . items ( )
159176 }
160177
178+ /// Get all updates from the room events as [`VectorDiff`].
179+ ///
180+ /// Be careful that each `VectorDiff` is returned only once!
181+ ///
182+ /// See [`AsVector`] to learn more.
183+ ///
184+ /// [`Update`]: matrix_sdk_base::linked_chunk::Update
185+ #[ allow( unused) ] // gonna be useful very soon! but we need it now for test purposes
186+ pub fn updates_as_vector_diffs ( & mut self ) -> Vec < VectorDiff < Event > > {
187+ self . chunks_updates_as_vectordiffs . take ( )
188+ }
189+
161190 /// Deduplicate `events` considering all events in `Self::chunks`.
162191 ///
163192 /// The returned tuple contains (i) the unique events, and (ii) the
@@ -315,6 +344,7 @@ impl RoomEvents {
315344
316345#[ cfg( test) ]
317346mod tests {
347+ use assert_matches:: assert_matches;
318348 use assert_matches2:: assert_let;
319349 use matrix_sdk_test:: event_factory:: EventFactory ;
320350 use ruma:: { user_id, EventId , OwnedEventId } ;
@@ -934,4 +964,57 @@ mod tests {
934964 // Ensure no chunk has been removed.
935965 assert_eq ! ( room_events. chunks( ) . count( ) , 3 ) ;
936966 }
967+
968+ #[ test]
969+ fn test_reset ( ) {
970+ let ( event_id_0, event_0) = new_event ( "$ev0" ) ;
971+ let ( event_id_1, event_1) = new_event ( "$ev1" ) ;
972+ let ( event_id_2, event_2) = new_event ( "$ev2" ) ;
973+ let ( event_id_3, event_3) = new_event ( "$ev3" ) ;
974+
975+ // Push some events.
976+ let mut room_events = RoomEvents :: new ( ) ;
977+ room_events. push_events ( [ event_0, event_1] ) ;
978+ room_events. push_gap ( Gap { prev_token : "raclette" . to_owned ( ) } ) ;
979+ room_events. push_events ( [ event_2] ) ;
980+
981+ // Read the updates as `VectorDiff`.
982+ let diffs = room_events. updates_as_vector_diffs ( ) ;
983+
984+ assert_eq ! ( diffs. len( ) , 2 ) ;
985+
986+ assert_matches ! (
987+ & diffs[ 0 ] ,
988+ VectorDiff :: Append { values } => {
989+ assert_eq!( values. len( ) , 2 ) ;
990+ assert_eq!( values[ 0 ] . event_id( ) , Some ( event_id_0) ) ;
991+ assert_eq!( values[ 1 ] . event_id( ) , Some ( event_id_1) ) ;
992+ }
993+ ) ;
994+ assert_matches ! (
995+ & diffs[ 1 ] ,
996+ VectorDiff :: Append { values } => {
997+ assert_eq!( values. len( ) , 1 ) ;
998+ assert_eq!( values[ 0 ] . event_id( ) , Some ( event_id_2) ) ;
999+ }
1000+ ) ;
1001+
1002+ // Now we can reset and see what happens.
1003+ room_events. reset ( ) ;
1004+ room_events. push_events ( [ event_3] ) ;
1005+
1006+ // Read the updates as `VectorDiff`.
1007+ let diffs = room_events. updates_as_vector_diffs ( ) ;
1008+
1009+ assert_eq ! ( diffs. len( ) , 2 ) ;
1010+
1011+ assert_matches ! ( & diffs[ 0 ] , VectorDiff :: Clear ) ;
1012+ assert_matches ! (
1013+ & diffs[ 1 ] ,
1014+ VectorDiff :: Append { values } => {
1015+ assert_eq!( values. len( ) , 1 ) ;
1016+ assert_eq!( values[ 0 ] . event_id( ) , Some ( event_id_3) ) ;
1017+ }
1018+ ) ;
1019+ }
9371020}
0 commit comments