Skip to content

Commit f76d83d

Browse files
committed
refactor(sdk): move formatted_caption_from to the SDK, rename it
Add the `markdown` feature to the SDK crate, otherwise we can't use `FormattedBody::markdown`. Refactor the pattern matching into an if, add tests to check its behaviour.
1 parent 6e75bdd commit f76d83d

File tree

2 files changed

+81
-25
lines changed
  • bindings/matrix-sdk-ffi/src/timeline
  • crates/matrix-sdk/src

2 files changed

+81
-25
lines changed

bindings/matrix-sdk-ffi/src/timeline/mod.rs

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ use ruma::{
4848
},
4949
receipt::ReceiptThread,
5050
room::message::{
51-
FormattedBody as RumaFormattedBody, ForwardThread, LocationMessageEventContent,
52-
MessageType, RoomMessageEventContentWithoutRelation,
51+
ForwardThread, LocationMessageEventContent, MessageType,
52+
RoomMessageEventContentWithoutRelation,
5353
},
5454
AnyMessageLikeEventContent,
5555
},
@@ -81,6 +81,7 @@ use crate::{
8181
mod content;
8282

8383
pub use content::MessageContent;
84+
use matrix_sdk::utils::formatted_body_from;
8485

8586
use crate::error::QueueWedgeError;
8687

@@ -289,7 +290,8 @@ impl Timeline {
289290
progress_watcher: Option<Box<dyn ProgressWatcher>>,
290291
use_send_queue: bool,
291292
) -> Arc<SendAttachmentJoinHandle> {
292-
let formatted_caption = formatted_caption_from(&caption, &formatted_caption);
293+
let formatted_caption =
294+
formatted_body_from(caption.as_deref(), formatted_caption.map(Into::into));
293295
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
294296
let base_image_info = BaseImageInfo::try_from(&image_info)
295297
.map_err(|_| RoomError::InvalidAttachmentData)?;
@@ -322,7 +324,8 @@ impl Timeline {
322324
progress_watcher: Option<Box<dyn ProgressWatcher>>,
323325
use_send_queue: bool,
324326
) -> Arc<SendAttachmentJoinHandle> {
325-
let formatted_caption = formatted_caption_from(&caption, &formatted_caption);
327+
let formatted_caption =
328+
formatted_body_from(caption.as_deref(), formatted_caption.map(Into::into));
326329
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
327330
let base_video_info: BaseVideoInfo = BaseVideoInfo::try_from(&video_info)
328331
.map_err(|_| RoomError::InvalidAttachmentData)?;
@@ -353,7 +356,8 @@ impl Timeline {
353356
progress_watcher: Option<Box<dyn ProgressWatcher>>,
354357
use_send_queue: bool,
355358
) -> Arc<SendAttachmentJoinHandle> {
356-
let formatted_caption = formatted_caption_from(&caption, &formatted_caption);
359+
let formatted_caption =
360+
formatted_body_from(caption.as_deref(), formatted_caption.map(Into::into));
357361
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
358362
let base_audio_info: BaseAudioInfo = BaseAudioInfo::try_from(&audio_info)
359363
.map_err(|_| RoomError::InvalidAttachmentData)?;
@@ -386,7 +390,8 @@ impl Timeline {
386390
progress_watcher: Option<Box<dyn ProgressWatcher>>,
387391
use_send_queue: bool,
388392
) -> Arc<SendAttachmentJoinHandle> {
389-
let formatted_caption = formatted_caption_from(&caption, &formatted_caption);
393+
let formatted_caption =
394+
formatted_body_from(caption.as_deref(), formatted_caption.map(Into::into));
390395
SendAttachmentJoinHandle::new(RUNTIME.spawn(async move {
391396
let base_audio_info: BaseAudioInfo = BaseAudioInfo::try_from(&audio_info)
392397
.map_err(|_| RoomError::InvalidAttachmentData)?;
@@ -714,24 +719,6 @@ impl Timeline {
714719
}
715720
}
716721

717-
/// Given a pair of optional `caption` and `formatted_caption` parameters,
718-
/// return a formatted caption:
719-
///
720-
/// - If a `formatted_caption` exists, return it.
721-
/// - If it doesn't exist but there is a `caption`, parse it as markdown and
722-
/// return the result.
723-
/// - Return `None` if there are no `caption` or `formatted_caption` parameters.
724-
fn formatted_caption_from(
725-
caption: &Option<String>,
726-
formatted_caption: &Option<FormattedBody>,
727-
) -> Option<RumaFormattedBody> {
728-
match (&caption, formatted_caption) {
729-
(None, None) => None,
730-
(Some(body), None) => RumaFormattedBody::markdown(body),
731-
(_, Some(formatted_body)) => Some(formatted_body.clone().into()),
732-
}
733-
}
734-
735722
/// A handle to perform actions onto a local echo.
736723
#[derive(uniffi::Object)]
737724
pub struct SendHandle {

crates/matrix-sdk/src/utils.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use futures_core::Stream;
2222
#[cfg(feature = "e2e-encryption")]
2323
use futures_util::StreamExt;
2424
use ruma::{
25-
events::{AnyMessageLikeEventContent, AnyStateEventContent},
25+
events::{room::message::FormattedBody, AnyMessageLikeEventContent, AnyStateEventContent},
2626
serde::Raw,
2727
RoomAliasId,
2828
};
@@ -218,10 +218,33 @@ pub fn is_room_alias_format_valid(alias: String) -> bool {
218218
has_valid_format && is_lowercase && RoomAliasId::parse(alias).is_ok()
219219
}
220220

221+
/// Given a pair of optional `body` and `formatted_body` parameters,
222+
/// returns a formatted body.
223+
///
224+
/// Return the formatted body if available, or interpret the `body` parameter as
225+
/// markdown, if provided.
226+
#[cfg(feature = "markdown")]
227+
pub fn formatted_body_from(
228+
body: Option<&str>,
229+
formatted_body: Option<FormattedBody>,
230+
) -> Option<FormattedBody> {
231+
if formatted_body.is_some() {
232+
formatted_body
233+
} else {
234+
body.and_then(FormattedBody::markdown)
235+
}
236+
}
237+
221238
#[cfg(test)]
222239
mod test {
240+
use assert_matches2::{assert_let, assert_matches};
241+
use ruma::events::room::message::FormattedBody;
242+
223243
use crate::utils::is_room_alias_format_valid;
224244

245+
#[cfg(feature = "markdown")]
246+
use crate::utils::formatted_body_from;
247+
225248
#[cfg(feature = "e2e-encryption")]
226249
#[test]
227250
fn test_channel_observable_get_set() {
@@ -282,4 +305,50 @@ mod test {
282305
fn test_is_room_alias_format_valid_when_has_valid_format() {
283306
assert!(is_room_alias_format_valid("#alias.test:domain.org".to_owned()))
284307
}
308+
309+
#[test]
310+
#[cfg(feature = "markdown")]
311+
fn test_formatted_body_from_nothing_returns_none() {
312+
assert_matches!(formatted_body_from(None, None), None);
313+
}
314+
315+
#[test]
316+
#[cfg(feature = "markdown")]
317+
fn test_formatted_body_from_only_formatted_body_returns_the_formatted_body() {
318+
let formatted_body = FormattedBody::html(r"<h1>Hello!</h1>");
319+
320+
assert_let!(
321+
Some(result_formatted_body) = formatted_body_from(None, Some(formatted_body.clone()))
322+
);
323+
324+
assert_eq!(formatted_body.body, result_formatted_body.body);
325+
assert_eq!(result_formatted_body.format, result_formatted_body.format);
326+
}
327+
328+
#[test]
329+
#[cfg(feature = "markdown")]
330+
fn test_formatted_body_from_markdown_body_returns_a_processed_formatted_body() {
331+
let markdown_body = Some(r"# Parsed");
332+
333+
assert_let!(Some(result_formatted_body) = formatted_body_from(markdown_body, None));
334+
335+
let expected_formatted_body = FormattedBody::html("<h1>Parsed</h1>\n".to_owned());
336+
assert_eq!(expected_formatted_body.body, result_formatted_body.body);
337+
assert_eq!(expected_formatted_body.format, result_formatted_body.format);
338+
}
339+
340+
#[test]
341+
#[cfg(feature = "markdown")]
342+
fn test_formatted_body_from_body_and_formatted_body_returns_the_formatted_body() {
343+
let markdown_body = Some(r"# Markdown");
344+
let formatted_body = FormattedBody::html(r"<h1>HTML</h1>");
345+
346+
assert_let!(
347+
Some(result_formatted_body) =
348+
formatted_body_from(markdown_body, Some(formatted_body.clone()))
349+
);
350+
351+
assert_eq!(formatted_body.body, result_formatted_body.body);
352+
assert_eq!(formatted_body.format, result_formatted_body.format);
353+
}
285354
}

0 commit comments

Comments
 (0)