matrix_sdk/widget/settings/
url_params.rs1use url::Url;
16use urlencoding::encode;
17
18pub const USER_ID: &str = "$matrix_user_id";
19pub const ROOM_ID: &str = "$matrix_room_id";
20pub const WIDGET_ID: &str = "$matrix_widget_id";
21pub const AVATAR_URL: &str = "$matrix_avatar_url";
22pub const DISPLAY_NAME: &str = "$matrix_display_name";
23pub const LANGUAGE: &str = "$org.matrix.msc2873.client_language";
24pub const CLIENT_THEME: &str = "$org.matrix.msc2873.client_theme";
25pub const CLIENT_ID: &str = "$org.matrix.msc2873.client_id";
26pub const DEVICE_ID: &str = "$org.matrix.msc2873.matrix_device_id";
27pub const HOMESERVER_URL: &str = "$org.matrix.msc4039.matrix_base_url";
28
29pub struct QueryProperties {
30 pub(crate) widget_id: String,
31 pub(crate) avatar_url: String,
32 pub(crate) display_name: String,
33 pub(crate) user_id: String,
34 pub(crate) room_id: String,
35 pub(crate) language: String,
36 pub(crate) client_theme: String,
37 pub(crate) client_id: String,
38 pub(crate) device_id: String,
39 pub(crate) homeserver_url: String,
40}
41
42pub fn replace_properties(url: &mut Url, props: QueryProperties) {
43 let replace_map: [(&str, String); 10] = [
44 (WIDGET_ID, encode(&props.widget_id).into()),
45 (AVATAR_URL, encode(&props.avatar_url).into()),
46 (DEVICE_ID, encode(&props.device_id).into()),
47 (DISPLAY_NAME, encode(&props.display_name).into()),
48 (HOMESERVER_URL, encode(&props.homeserver_url).into()),
49 (USER_ID, encode(&props.user_id).into()),
50 (ROOM_ID, encode(&props.room_id).into()),
51 (LANGUAGE, encode(&props.language).into()),
52 (CLIENT_THEME, encode(&props.client_theme).into()),
53 (CLIENT_ID, encode(&props.client_id).into()),
54 ]
55 .map(|to_replace| {
56 (to_replace.0.get(1..).unwrap(), to_replace.1)
58 });
59
60 let s = url.as_str();
61 let Some(beginning) = s.split_once('$').map(|s| s.0) else {
62 return;
64 };
65 let mut result = String::from(beginning);
66 for section in s.split('$').skip(1) {
67 let mut section_added = false;
68 for (old, new) in &replace_map {
69 section.split_once(|c: char| !(c.is_ascii_alphanumeric() || c == '.' || c == '_'));
70 if section.starts_with(old) {
72 result.push_str(new);
73 if let Some(rest) = section.get(old.len()..) {
74 result.push_str(rest);
75 }
76 section_added = true;
77 }
78 }
79 if !section_added {
80 result.push_str(section);
81 }
82 }
83 *url = Url::parse(&result).unwrap();
84}
85
86#[cfg(test)]
87mod tests {
88 use url::Url;
89
90 use super::{replace_properties, QueryProperties};
91
92 const EXAMPLE_URL: &str = "\
93 https://my.widget.org/custom/path/using/$matrix_display_name/in/it\
94 ?widgetId=$matrix_widget_id\
95 &deviceId=$org.matrix.msc2873.matrix_device_id\
96 &avatarUrl=$matrix_avatar_url\
97 &displayName=$matrix_display_name\
98 &lang=$org.matrix.msc2873.client_language\
99 &theme=$org.matrix.msc2873.client_theme\
100 &clientId=$org.matrix.msc2873.client_id\
101 &baseUrl=$org.matrix.msc4039.matrix_base_url\
102 #andAHashWithA$org.matrix.msc2873.client_themeThemeAndTheClientId:$org.matrix.msc2873.client_id\
103 ";
104
105 fn get_example_props() -> QueryProperties {
106 QueryProperties {
107 widget_id: String::from("!@/abc_widget_id"),
108 avatar_url: "!@/abc_avatar_url".to_owned(),
109 display_name: "I_AM_THE_user".to_owned(),
110 user_id: "!@/abc_user_id".to_owned(),
111 room_id: "!@/abc_room_id".to_owned(),
112 language: "!@/abc_language".to_owned(),
113 client_theme: "light".to_owned(),
114 client_id: "12345678".to_owned(),
115 device_id: "!@/abc_device_id".to_owned(),
116 homeserver_url: "https://abc_base_url/".to_owned(),
117 }
118 }
119
120 fn get_example_url() -> Url {
121 Url::parse(EXAMPLE_URL).expect("EXAMPLE_URL is malformatted")
122 }
123
124 #[test]
125 fn replace_all_properties() {
126 let mut url = get_example_url();
127
128 const CONVERTED_URL: &str = "\
129 https://my.widget.org/custom/path/using/I_AM_THE_user/in/it\
130 ?widgetId=%21%40%2Fabc_widget_id\
131 &deviceId=%21%40%2Fabc_device_id\
132 &avatarUrl=%21%40%2Fabc_avatar_url\
133 &displayName=I_AM_THE_user\
134 &lang=%21%40%2Fabc_language\
135 &theme=light\
136 &clientId=12345678\
137 &baseUrl=https%3A%2F%2Fabc_base_url%2F\
138 #andAHashWithAlightThemeAndTheClientId:12345678\
139 ";
140
141 replace_properties(&mut url, get_example_props());
142 assert_eq!(url.as_str(), CONVERTED_URL);
143 }
144}