diff --git a/Cargo.lock b/Cargo.lock index 45f15c86..235bee5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3780,9 +3780,9 @@ dependencies = [ [[package]] name = "ruma-client-api" -version = "0.15.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bcfd3a3853ffdd151fc228441dd9c9e3d835ac85560dface7abda50b3888791" +checksum = "d1e72bc731b4dc8b569aa83915f13e419144b67110d858c65bb74aa05e2dc4b7" dependencies = [ "assign", "bytes", @@ -3797,9 +3797,9 @@ dependencies = [ [[package]] name = "ruma-common" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e629a01f359234798531a99ba83997abd4c15a65b5bcb8354c4171b59c25be" +checksum = "716889595f4edc3cfeb94d9f122e413f73e37d7d80ea1c14196e1004241a3889" dependencies = [ "base64", "bytes", @@ -3852,9 +3852,9 @@ dependencies = [ [[package]] name = "ruma-macros" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7cd8cf8771aaca36042fb7659f4647b05e74a2058d843474dde5e51a56cd85" +checksum = "0f82e91eb61cd86d9287303133ee55b54618eccb75a522cc22a42c15f5bda340" dependencies = [ "once_cell", "proc-macro-crate", diff --git a/src/session/content/room_history/message_row/text.rs b/src/session/content/room_history/message_row/text.rs index 44f0a4a1..5f1b1aad 100644 --- a/src/session/content/room_history/message_row/text.rs +++ b/src/session/content/room_history/message_row/text.rs @@ -10,7 +10,7 @@ use log::warn; use matrix_sdk::ruma::{ events::room::message::{FormattedBody, MessageFormat}, matrix_uri::MatrixId, - MatrixUri, + MatrixToUri, MatrixUri, }; use sourceview::prelude::*; @@ -18,7 +18,7 @@ use super::ContentFormat; use crate::{ components::{LabelWithWidgets, Pill, DEFAULT_PLACEHOLDER}, session::{room::Member, Room, UserExt}, - utils::{parse_matrix_to_uri, EMOJI_REGEX}, + utils::EMOJI_REGEX, }; enum WithMentions<'a> { @@ -376,11 +376,12 @@ fn extract_mentions(s: &str, room: &Room) -> (String, Vec) { }; let uri = &link[..uri_end]; + let uri = html_escape::decode_html_entities(uri); - let id = if let Ok(mx_uri) = MatrixUri::parse(uri) { + let id = if let Ok(mx_uri) = MatrixUri::parse(&uri) { mx_uri.id().to_owned() - } else if let Ok((id, _)) = parse_matrix_to_uri(uri) { - id + } else if let Ok(mx_to_uri) = MatrixToUri::parse(&uri) { + mx_to_uri.id().to_owned() } else { continue; }; diff --git a/src/session/mod.rs b/src/session/mod.rs index b37be46e..d3171cfb 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -41,7 +41,7 @@ use matrix_sdk::{ GlobalAccountDataEvent, }, matrix_uri::MatrixId, - MatrixUri, OwnedRoomOrAliasId, OwnedServerName, RoomId, RoomOrAliasId, + MatrixToUri, MatrixUri, OwnedRoomOrAliasId, OwnedServerName, RoomId, RoomOrAliasId, }, Client, HttpError, RumaApiError, }; @@ -66,7 +66,7 @@ use crate::{ secret::{self, StoredSession}, session::sidebar::ItemList, spawn, spawn_tokio, toast, - utils::{check_if_reachable, parse_matrix_to_uri}, + utils::check_if_reachable, Window, }; @@ -836,11 +836,13 @@ fn parse_room(room: &str) -> Option<(OwnedRoomOrAliasId, Vec)> _ => None, }) .or_else(|| { - parse_matrix_to_uri(room) + MatrixToUri::parse(room) .ok() - .and_then(|(id, via)| match id { - MatrixId::Room(room_id) => Some((room_id.into(), via)), - MatrixId::RoomAlias(room_alias) => Some((room_alias.into(), via)), + .and_then(|uri| match uri.id() { + MatrixId::Room(room_id) => Some((room_id.clone().into(), uri.via().to_owned())), + MatrixId::RoomAlias(room_alias) => { + Some((room_alias.clone().into(), uri.via().to_owned())) + } _ => None, }) }) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 30ebcb64..715bac17 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -18,11 +18,6 @@ use gtk::{ use matrix_sdk::ruma::{EventId, OwnedEventId, OwnedTransactionId, TransactionId, UInt}; use once_cell::sync::Lazy; use regex::Regex; -use ruma::{ - exports::percent_encoding::percent_decode_str, matrix_uri::MatrixId, IdParseError, - MatrixIdError, MatrixToError, OwnedServerName, RoomAliasId, RoomId, ServerName, UserId, -}; -use url::form_urlencoded; /// Returns an expression that is the and’ed result of the given boolean /// expressions. @@ -230,73 +225,3 @@ pub static EMOJI_REGEX: Lazy = Lazy::new(|| { ) .unwrap() }); - -const MATRIX_TO_BASE_URL: &str = "https://matrix.to/#/"; - -/// Parse a matrix.to URI. -/// -/// Ruma's parsing fails with non-percent-encoded identifiers, which is the -/// format of permalinks provided by Element Web. -pub fn parse_matrix_to_uri(uri: &str) -> Result<(MatrixId, Vec), IdParseError> { - let s = uri - .strip_prefix(MATRIX_TO_BASE_URL) - .ok_or(MatrixToError::WrongBaseUrl)?; - let s = s.strip_suffix('/').unwrap_or(s); - - let mut parts = s.split('?'); - let ids_part = parts.next().ok_or(MatrixIdError::NoIdentifier)?; - let mut ids = ids_part.split('/'); - - let first = ids.next().ok_or(MatrixIdError::NoIdentifier)?; - let first_id = percent_decode_str(first).decode_utf8()?; - - let id: MatrixId = match first_id.as_bytes()[0] { - b'!' => { - let room_id = RoomId::parse(&first_id)?; - - if let Some(second) = ids.next() { - let second_id = percent_decode_str(second).decode_utf8()?; - let event_id = EventId::parse(&second_id)?; - (room_id, event_id).into() - } else { - room_id.into() - } - } - b'#' => { - let room_id = RoomAliasId::parse(&first_id)?; - - if let Some(second) = ids.next() { - let second_id = percent_decode_str(second).decode_utf8()?; - let event_id = EventId::parse(&second_id)?; - (room_id, event_id).into() - } else { - room_id.into() - } - } - b'@' => UserId::parse(&first_id)?.into(), - b'$' => return Err(MatrixIdError::MissingRoom.into()), - _ => return Err(MatrixIdError::UnknownIdentifier.into()), - }; - - if ids.next().is_some() { - return Err(MatrixIdError::TooManyIdentifiers.into()); - } - - let via = parts - .next() - .map(|query| { - let query = html_escape::decode_html_entities(query); - let query_parts = form_urlencoded::parse(query.as_bytes()); - query_parts - .filter_map(|(key, value)| (key == "via").then(|| ServerName::parse(&value))) - .collect::, _>>() - }) - .transpose()? - .unwrap_or_default(); - - if parts.next().is_some() { - return Err(MatrixToError::InvalidUrl.into()); - } - - Ok((id, via)) -}