Skip to content

Commit

Permalink
sdk: fetch unstable_features supported by homeserver
Browse files Browse the repository at this point in the history
Signed-off-by: hanadi92 <hanadi.tamimi@gmail.com>
  • Loading branch information
hanadi92 committed Mar 6, 2024
1 parent a204b29 commit ffda84c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
5 changes: 4 additions & 1 deletion crates/matrix-sdk/src/client/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{fmt, sync::Arc};
use std::{collections::BTreeMap, fmt, sync::Arc};

use matrix_sdk_base::{store::StoreConfig, BaseClient};
use ruma::{
Expand Down Expand Up @@ -90,6 +90,7 @@ pub struct ClientBuilder {
request_config: RequestConfig,
respect_login_well_known: bool,
server_versions: Option<Box<[MatrixVersion]>>,
unstable_features: Option<BTreeMap<String, bool>>,
handle_refresh_tokens: bool,
base_client: Option<BaseClient>,
#[cfg(feature = "e2e-encryption")]
Expand All @@ -107,6 +108,7 @@ impl ClientBuilder {
request_config: Default::default(),
respect_login_well_known: true,
server_versions: None,
unstable_features: None,
handle_refresh_tokens: false,
base_client: None,
#[cfg(feature = "e2e-encryption")]
Expand Down Expand Up @@ -508,6 +510,7 @@ impl ClientBuilder {
http_client,
base_client,
self.server_versions,
self.unstable_features,
self.respect_login_well_known,
event_cache,
#[cfg(feature = "e2e-encryption")]
Expand Down
67 changes: 67 additions & 0 deletions crates/matrix-sdk/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ pub(crate) struct ClientInner {
/// The Matrix versions the server supports (well-known ones only)
server_versions: OnceCell<Box<[MatrixVersion]>>,

/// The unstable features and their on/off state on the server
unstable_features: OnceCell<BTreeMap<String, bool>>,

/// Collection of locks individual client methods might want to use, either
/// to ensure that only a single call to a method happens at once or to
/// deduplicate multiple calls to a method.
Expand Down Expand Up @@ -292,6 +295,7 @@ impl ClientInner {
http_client: HttpClient,
base_client: BaseClient,
server_versions: Option<Box<[MatrixVersion]>>,
unstable_features: Option<BTreeMap<String, bool>>,
respect_login_well_known: bool,
event_cache: OnceCell<EventCache>,
#[cfg(feature = "e2e-encryption")] encryption_settings: EncryptionSettings,
Expand All @@ -305,6 +309,7 @@ impl ClientInner {
base_client,
locks: Default::default(),
server_versions: OnceCell::new_with(server_versions),
unstable_features: OnceCell::new_with(unstable_features),
typing_notice_times: Default::default(),
event_handlers: Default::default(),
notification_handlers: Default::default(),
Expand Down Expand Up @@ -1401,6 +1406,49 @@ impl Client {
Ok(server_versions)
}

/// Fetch unstable_features from homeserver
async fn request_unstable_features(&self) -> HttpResult<BTreeMap<String, bool>> {
let unstable_features: BTreeMap<String, bool> = self
.inner
.http_client
.send(
get_supported_versions::Request::new(),
None,
self.homeserver().to_string(),
None,
&[MatrixVersion::V1_0],
Default::default(),
)
.await?
.unstable_features;

Ok(unstable_features)
}

/// Get unstable features from `request_unstable_features` or cache
///
/// # Examples
///
/// ```no_run
/// # use matrix_sdk::{Client, config::SyncSettings};
/// # use url::Url;
/// # async {
/// # let homeserver = Url::parse("http://localhost:8080")?;
/// # let mut client = Client::new(homeserver).await?;
/// let unstable_features = client.unstable_features().await.unwrap();
/// let msc_x = unstable_features.get("msc_x").unwrap_or(&false);
/// # anyhow::Ok(()) };
/// ```
pub async fn unstable_features(&self) -> HttpResult<&BTreeMap<String, bool>> {
let unstable_features = self
.inner
.unstable_features
.get_or_try_init(|| self.request_unstable_features())
.await?;

Ok(unstable_features)
}

/// Get information of all our own devices.
///
/// # Examples
Expand Down Expand Up @@ -2006,6 +2054,7 @@ impl Client {
self.inner.http_client.clone(),
self.inner.base_client.clone_with_in_memory_state_store(),
self.inner.server_versions.get().cloned(),
self.inner.unstable_features.get().cloned(),
self.inner.respect_login_well_known,
self.inner.event_cache.clone(),
#[cfg(feature = "e2e-encryption")]
Expand Down Expand Up @@ -2269,4 +2318,22 @@ pub(crate) mod tests {
assert_eq!(result.avatar_url.clone().unwrap().to_string(), "mxc://example.me/someid");
assert!(!response.limited);
}

#[async_test]
async fn test_homeserver_server_versions() {
let server = MockServer::start().await;
let client = logged_in_client(Some(server.uri())).await;

Mock::given(method("GET"))
.and(path("_matrix/client/versions"))
.respond_with(
ResponseTemplate::new(200).set_body_json(&*test_json::api_responses::VERSIONS),
)
.mount(&server)
.await;
let unstable_features = client.request_unstable_features().await.unwrap();

assert_eq!(unstable_features.get("org.matrix.e2e_cross_signing"), Some(&true));
assert_eq!(unstable_features, client.unstable_features().await.unwrap().clone())
}
}

0 comments on commit ffda84c

Please sign in to comment.