Skip to content

Commit 5d77f32

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 5d77f32

File tree

2 files changed

+83
-24
lines changed
  • bindings/matrix-sdk-ffi/src/timeline
  • crates/matrix-sdk/src

2 files changed

+83
-24
lines changed

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

+11-24
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

+72
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use std::sync::{Arc, RwLock};
2121
use futures_core::Stream;
2222
#[cfg(feature = "e2e-encryption")]
2323
use futures_util::StreamExt;
24+
#[cfg(feature = "markdown")]
25+
use ruma::events::room::message::FormattedBody;
2426
use ruma::{
2527
events::{AnyMessageLikeEventContent, AnyStateEventContent},
2628
serde::Raw,
@@ -218,8 +220,32 @@ pub fn is_room_alias_format_valid(alias: String) -> bool {
218220
has_valid_format && is_lowercase && RoomAliasId::parse(alias).is_ok()
219221
}
220222

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

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

0 commit comments

Comments
 (0)