Skip to content

Commit 059bcd2

Browse files
committed
fix(sdk): new_local returns an Option.
We can't use `LatestEventValue::None` as an optional value anymore, since it erases the previous `LatestEventValue`. This patch updates `LatestEventValueBuilder::new_local` to return an `Option` to handle all the cases where a local value cannot be computed.
1 parent 4e90cea commit 059bcd2

File tree

2 files changed

+95
-28
lines changed

2 files changed

+95
-28
lines changed

crates/matrix-sdk/src/latest_events/latest_event.rs

Lines changed: 89 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ impl LatestEvent {
118118
let new_value =
119119
LatestEventValueBuilder::new_remote(room_event_cache, own_user_id, power_levels).await;
120120

121+
info!(value = ?new_value, "Computed a remote `LatestEventValue`");
122+
121123
self.update(new_value).await;
122124
}
123125

@@ -139,7 +141,11 @@ impl LatestEvent {
139141
)
140142
.await;
141143

142-
self.update(new_value).await;
144+
info!(value = ?new_value, "Computed a local `LatestEventValue`");
145+
146+
if let Some(new_value) = new_value {
147+
self.update(new_value).await;
148+
}
143149
}
144150

145151
/// Update [`Self::current_value`], and persist the `new_value` in the
@@ -657,7 +663,7 @@ impl LatestEventValueBuilder {
657663
format!("`LatestEventValueBuilder::new_remote` for {:?}", room_event_cache.room_id())
658664
);
659665

660-
let value = if let Ok(Some(event)) = room_event_cache
666+
if let Ok(Some(event)) = room_event_cache
661667
.rfind_map_event_in_memory_by(|event, previous_event_id| {
662668
filter_timeline_event(event, previous_event_id, own_user_id, power_levels)
663669
.then(|| event.clone())
@@ -667,11 +673,7 @@ impl LatestEventValueBuilder {
667673
LatestEventValue::Remote(event)
668674
} else {
669675
LatestEventValue::default()
670-
};
671-
672-
info!(?value, "Computed a remote `LatestEventValue`");
673-
674-
value
676+
}
675677
}
676678

677679
/// Create a new [`LatestEventValue::LocalIsSending`] or
@@ -682,15 +684,15 @@ impl LatestEventValueBuilder {
682684
room_event_cache: &RoomEventCache,
683685
own_user_id: &UserId,
684686
power_levels: Option<&RoomPowerLevels>,
685-
) -> LatestEventValue {
687+
) -> Option<LatestEventValue> {
686688
use crate::send_queue::{LocalEcho, LocalEchoContent};
687689

688690
let _timer = timer!(
689691
tracing::Level::INFO,
690692
format!("`LatestEventValueBuilder::new_local` for {:?}", room_event_cache.room_id())
691693
);
692694

693-
let value = match send_queue_update {
695+
Some(match send_queue_update {
694696
// A new local event is being sent.
695697
//
696698
// Let's create the `LatestEventValue` and push it in the buffer of values.
@@ -724,7 +726,7 @@ impl LatestEventValueBuilder {
724726

725727
value
726728
} else {
727-
LatestEventValue::None
729+
return None;
728730
}
729731
}
730732

@@ -734,12 +736,12 @@ impl LatestEventValueBuilder {
734736
"Failed to deserialize an event from `RoomSendQueueUpdate::NewLocalEvent`"
735737
);
736738

737-
LatestEventValue::None
739+
return None;
738740
}
739741
}
740742
}
741743

742-
LocalEchoContent::React { .. } => LatestEventValue::None,
744+
LocalEchoContent::React { .. } => return None,
743745
},
744746

745747
// A local event has been cancelled before being sent.
@@ -783,7 +785,7 @@ impl LatestEventValueBuilder {
783785
| LatestEventValue::LocalCannotBeSent(local_value)
784786
// Technically impossible, but it's not harmful to handle this that way.
785787
| LatestEventValue::LocalHasBeenSent(local_value ) => {
786-
return LatestEventValue::LocalHasBeenSent(local_value);
788+
return Some(LatestEventValue::LocalHasBeenSent(local_value));
787789
}
788790
LatestEventValue::Remote(_) | LatestEventValue::None => unreachable!("Impossible to get a remote `LatestEventValue`"),
789791
}
@@ -826,7 +828,7 @@ impl LatestEventValueBuilder {
826828
"Failed to deserialize an event from `RoomSendQueueUpdate::ReplacedLocalEvent`"
827829
);
828830

829-
return LatestEventValue::None;
831+
return None;
830832
}
831833
}
832834
}
@@ -875,12 +877,8 @@ impl LatestEventValueBuilder {
875877
// A media upload has made progress.
876878
//
877879
// Nothing to do here.
878-
RoomSendQueueUpdate::MediaUpload { .. } => LatestEventValue::None,
879-
};
880-
881-
info!(?value, "Computed a local `LatestEventValue`");
882-
883-
value
880+
RoomSendQueueUpdate::MediaUpload { .. } => return None,
881+
})
884882
}
885883

886884
/// Get the last [`LatestEventValue`] from the local latest event values if
@@ -1887,7 +1885,7 @@ mod tests_latest_event_value_builder {
18871885
RoomState,
18881886
deserialized_responses::TimelineEventKind,
18891887
linked_chunk::{ChunkIdentifier, LinkedChunkId, Position, Update},
1890-
store::SerializableEventContent,
1888+
store::{ChildTransactionId, SerializableEventContent},
18911889
};
18921890
use matrix_sdk_test::{async_test, event_factory::EventFactory};
18931891
use ruma::{
@@ -1906,7 +1904,10 @@ mod tests_latest_event_value_builder {
19061904
};
19071905
use crate::{
19081906
Client, Error,
1909-
send_queue::{AbstractProgress, LocalEcho, LocalEchoContent, RoomSendQueue, SendHandle},
1907+
send_queue::{
1908+
AbstractProgress, LocalEcho, LocalEchoContent, RoomSendQueue, SendHandle,
1909+
SendReactionHandle,
1910+
},
19101911
test_utils::mocks::MatrixMockServer,
19111912
};
19121913

@@ -1934,7 +1935,7 @@ mod tests_latest_event_value_builder {
19341935
( $latest_event_value:expr, $pattern:path => with body = $body:expr ) => {
19351936
assert_matches!(
19361937
$latest_event_value,
1937-
$pattern (local_event) => {
1938+
Some( $pattern (local_event)) => {
19381939
assert_matches!(
19391940
local_event.content.deserialize().unwrap(),
19401941
AnyMessageLikeEventContent::RoomMessage(message_content) => {
@@ -2051,7 +2052,7 @@ mod tests_latest_event_value_builder {
20512052
}
20522053

20532054
#[async_test]
2054-
async fn test_local_new_local_event() {
2055+
async fn test_local_new_local_event_with_content_of_kind_event() {
20552056
let (client, _room_id, room_send_queue, room_event_cache) = local_prelude().await;
20562057
let user_id = client.user_id().unwrap();
20572058

@@ -2089,7 +2090,8 @@ mod tests_latest_event_value_builder {
20892090
}
20902091

20912092
#[async_test]
2092-
async fn test_local_new_local_event_when_previous_local_event_cannot_be_sent() {
2093+
async fn test_local_new_local_event_with_content_of_kind_event_when_previous_local_event_cannot_be_sent()
2094+
{
20932095
let (client, _room_id, room_send_queue, room_event_cache) = local_prelude().await;
20942096
let user_id = client.user_id().unwrap();
20952097

@@ -2155,6 +2157,64 @@ mod tests_latest_event_value_builder {
21552157
assert_matches!(&buffer.buffer[1].1, LatestEventValue::LocalCannotBeSent(_));
21562158
}
21572159

2160+
#[async_test]
2161+
async fn test_local_new_local_event_with_content_of_kind_react() {
2162+
let (client, _room_id, room_send_queue, room_event_cache) = local_prelude().await;
2163+
let user_id = client.user_id().unwrap();
2164+
2165+
let mut buffer = LatestEventValuesForLocalEvents::new();
2166+
2167+
// Receiving one `NewLocalEvent` with content of kind event.
2168+
let transaction_id_0 = {
2169+
let transaction_id = OwnedTransactionId::from("txnid0");
2170+
let content = new_local_echo_content(&room_send_queue, &transaction_id, "A");
2171+
2172+
let update = RoomSendQueueUpdate::NewLocalEvent(LocalEcho {
2173+
transaction_id: transaction_id.clone(),
2174+
content,
2175+
});
2176+
2177+
// The `LatestEventValue` matches the new local event.
2178+
assert_local_value_matches_room_message_with_body!(
2179+
LatestEventValueBuilder::new_local(&update, &mut buffer, &room_event_cache, user_id, None).await,
2180+
LatestEventValue::LocalIsSending => with body = "A"
2181+
);
2182+
2183+
transaction_id
2184+
};
2185+
2186+
// Receiving one `NewLocalEvent` with content of kind react! This time, it is
2187+
// ignored.
2188+
{
2189+
let transaction_id = OwnedTransactionId::from("txnid1");
2190+
let content = LocalEchoContent::React {
2191+
key: "<< 1".to_owned(),
2192+
send_handle: SendReactionHandle::new(
2193+
room_send_queue.clone(),
2194+
ChildTransactionId::new(),
2195+
),
2196+
applies_to: transaction_id_0,
2197+
};
2198+
2199+
let update = RoomSendQueueUpdate::NewLocalEvent(LocalEcho { transaction_id, content });
2200+
2201+
// The `LatestEventValue` matches the previous local event.
2202+
assert_matches!(
2203+
LatestEventValueBuilder::new_local(
2204+
&update,
2205+
&mut buffer,
2206+
&room_event_cache,
2207+
user_id,
2208+
None
2209+
)
2210+
.await,
2211+
None
2212+
);
2213+
}
2214+
2215+
assert_eq!(buffer.buffer.len(), 1);
2216+
}
2217+
21582218
#[async_test]
21592219
async fn test_local_cancelled_local_event() {
21602220
let (client, _room_id, room_send_queue, room_event_cache) = local_prelude().await;
@@ -2239,7 +2299,7 @@ mod tests_latest_event_value_builder {
22392299
None
22402300
)
22412301
.await,
2242-
LatestEventValue::None
2302+
Some(LatestEventValue::None)
22432303
);
22442304

22452305
assert!(buffer.buffer.is_empty());
@@ -2446,7 +2506,7 @@ mod tests_latest_event_value_builder {
24462506
None
24472507
)
24482508
.await,
2449-
LatestEventValue::None
2509+
Some(LatestEventValue::None)
24502510
);
24512511

24522512
assert_eq!(buffer.buffer.len(), 0);
@@ -2640,7 +2700,7 @@ mod tests_latest_event_value_builder {
26402700
None
26412701
)
26422702
.await,
2643-
LatestEventValue::None
2703+
None
26442704
);
26452705

26462706
assert_eq!(buffer.buffer.len(), 1);
@@ -2713,6 +2773,7 @@ mod tests_latest_event_value_builder {
27132773
None,
27142774
)
27152775
.await
2776+
.unwrap()
27162777
=> with body = "hello"
27172778
);
27182779
}

crates/matrix-sdk/src/send_queue/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,6 +2772,12 @@ pub struct SendReactionHandle {
27722772
}
27732773

27742774
impl SendReactionHandle {
2775+
/// Creates a new [`SendReactionHandle`].
2776+
#[cfg(test)]
2777+
pub(crate) fn new(room: RoomSendQueue, transaction_id: ChildTransactionId) -> Self {
2778+
Self { room, transaction_id }
2779+
}
2780+
27752781
/// Abort the sending of the reaction.
27762782
///
27772783
/// Will return true if the reaction could be aborted, false if it's been

0 commit comments

Comments
 (0)