matrix_sdk: Add get_public_rooms* methods to Client
This also adds a RoomSearchBuilder for making get_public_rooms_filtered requests and a test for each method.master
parent
676d547161
commit
4dbe785bd7
|
@ -23,6 +23,7 @@ use std::result::Result as StdResult;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use matrix_sdk_common::instant::{Duration, Instant};
|
use matrix_sdk_common::instant::{Duration, Instant};
|
||||||
|
use matrix_sdk_common::js_int::UInt;
|
||||||
use matrix_sdk_common::locks::RwLock;
|
use matrix_sdk_common::locks::RwLock;
|
||||||
use matrix_sdk_common::uuid::Uuid;
|
use matrix_sdk_common::uuid::Uuid;
|
||||||
|
|
||||||
|
@ -248,6 +249,8 @@ impl SyncSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
use api::r0::account::register;
|
use api::r0::account::register;
|
||||||
|
use api::r0::directory::get_public_rooms;
|
||||||
|
use api::r0::directory::get_public_rooms_filtered;
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use api::r0::keys::{claim_keys, get_keys, upload_keys, KeyAlgorithm};
|
use api::r0::keys::{claim_keys, get_keys, upload_keys, KeyAlgorithm};
|
||||||
use api::r0::membership::{
|
use api::r0::membership::{
|
||||||
|
@ -646,6 +649,94 @@ impl Client {
|
||||||
self.send(request).await
|
self.send(request).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Search the homeserver's directory of public rooms.
|
||||||
|
///
|
||||||
|
/// Returns a `get_public_rooms::Response`, an empty response.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `limit` - The number of `PublicRoomsChunk`s in each response.
|
||||||
|
///
|
||||||
|
/// * `since` - Pagination token from a previous request.
|
||||||
|
///
|
||||||
|
/// * `server` - The name of the server, if `None` the requested server is used.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```no_run
|
||||||
|
/// use matrix_sdk::{Client, RoomSearchBuilder};
|
||||||
|
/// # use matrix_sdk::api::r0::directory::get_public_rooms;
|
||||||
|
/// # use url::Url;
|
||||||
|
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||||
|
/// # let limit = Some(10);
|
||||||
|
/// # let since = Some("since token");
|
||||||
|
/// # let server = Some("server name");
|
||||||
|
///
|
||||||
|
/// let mut cli = Client::new(homeserver).unwrap();
|
||||||
|
/// # use futures::executor::block_on;
|
||||||
|
/// # block_on(async {
|
||||||
|
/// assert!(cli.get_public_rooms(
|
||||||
|
/// limit,
|
||||||
|
/// since,
|
||||||
|
/// server
|
||||||
|
/// ).await.is_ok());
|
||||||
|
/// # });
|
||||||
|
/// ```
|
||||||
|
pub async fn get_public_rooms(
|
||||||
|
&self,
|
||||||
|
limit: Option<u32>,
|
||||||
|
since: Option<&str>,
|
||||||
|
server: Option<&str>,
|
||||||
|
) -> Result<get_public_rooms::Response> {
|
||||||
|
let limit = limit.map(|n| UInt::try_from(n).ok()).flatten();
|
||||||
|
let since = since.map(ToString::to_string);
|
||||||
|
let server = server.map(ToString::to_string);
|
||||||
|
|
||||||
|
let request = get_public_rooms::Request {
|
||||||
|
limit,
|
||||||
|
since,
|
||||||
|
server,
|
||||||
|
};
|
||||||
|
self.send(request).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Search the homeserver's directory of public rooms filtered.
|
||||||
|
///
|
||||||
|
/// Returns a `get_public_rooms_filtered::Response`, an empty response.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `room_search` - The easiest way to create this request is using the `RoomSearchBuilder`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::convert::TryFrom;
|
||||||
|
/// # use matrix_sdk::{Client, RoomSearchBuilder};
|
||||||
|
/// # use matrix_sdk::api::r0::directory::get_public_rooms_filtered::{self, RoomNetwork, Filter};
|
||||||
|
/// # use url::Url;
|
||||||
|
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||||
|
/// # let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
/// # rt.block_on(async {
|
||||||
|
/// # let last_sync_token = "".to_string();
|
||||||
|
/// let mut client = Client::new(homeserver).unwrap();
|
||||||
|
///
|
||||||
|
/// let generic_search_term = Some("matrix-rust-sdk".to_string());
|
||||||
|
/// let mut builder = RoomSearchBuilder::new();
|
||||||
|
/// builder
|
||||||
|
/// .filter(Filter { generic_search_term, })
|
||||||
|
/// .since(last_sync_token)
|
||||||
|
/// .room_network(RoomNetwork::Matrix);
|
||||||
|
///
|
||||||
|
/// client.get_public_rooms_filtered(builder).await.is_err();
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
pub async fn get_public_rooms_filtered<R: Into<get_public_rooms_filtered::Request>>(
|
||||||
|
&self,
|
||||||
|
room_search: R,
|
||||||
|
) -> Result<get_public_rooms_filtered::Response> {
|
||||||
|
let request = room_search.into();
|
||||||
|
self.send(request).await
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a room using the `RoomBuilder` and send the request.
|
/// Create a room using the `RoomBuilder` and send the request.
|
||||||
///
|
///
|
||||||
/// Sends a request to `/_matrix/client/r0/createRoom`, returns a `create_room::Response`,
|
/// Sends a request to `/_matrix/client/r0/createRoom`, returns a `create_room::Response`,
|
||||||
|
@ -951,7 +1042,7 @@ impl Client {
|
||||||
.body(body)
|
.body(body)
|
||||||
.header(reqwest::header::CONTENT_TYPE, "application/json")
|
.header(reqwest::header::CONTENT_TYPE, "application/json")
|
||||||
}
|
}
|
||||||
method => panic!("Unsuported method {}", method),
|
method => panic!("Unsupported method {}", method),
|
||||||
};
|
};
|
||||||
|
|
||||||
let request_builder = if requires_auth {
|
let request_builder = if requires_auth {
|
||||||
|
@ -1395,15 +1486,18 @@ impl Client {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{
|
use super::{
|
||||||
api::r0::uiaa::AuthData, ban_user, create_receipt, create_typing_event, forget_room,
|
api::r0::uiaa::AuthData,
|
||||||
invite_user, kick_user, leave_room, register::RegistrationKind, set_read_marker,
|
ban_user, create_receipt, create_typing_event, forget_room, get_public_rooms,
|
||||||
Invite3pid, MessageEventContent,
|
get_public_rooms_filtered::{self, Filter},
|
||||||
|
invite_user, kick_user, leave_room,
|
||||||
|
register::RegistrationKind,
|
||||||
|
set_read_marker, Invite3pid, MessageEventContent,
|
||||||
};
|
};
|
||||||
use super::{Client, ClientConfig, Session, SyncSettings, Url};
|
use super::{Client, ClientConfig, Session, SyncSettings, Url};
|
||||||
use crate::events::collections::all::RoomEvent;
|
use crate::events::collections::all::RoomEvent;
|
||||||
use crate::events::room::message::TextMessageEventContent;
|
use crate::events::room::message::TextMessageEventContent;
|
||||||
use crate::identifiers::{EventId, RoomId, RoomIdOrAliasId, UserId};
|
use crate::identifiers::{EventId, RoomId, RoomIdOrAliasId, UserId};
|
||||||
use crate::RegistrationBuilder;
|
use crate::{RegistrationBuilder, RoomSearchBuilder};
|
||||||
|
|
||||||
use matrix_sdk_base::JsonStore;
|
use matrix_sdk_base::JsonStore;
|
||||||
use matrix_sdk_test::{test_json, EventBuilder, EventsJson};
|
use matrix_sdk_test::{test_json, EventBuilder, EventsJson};
|
||||||
|
@ -1751,6 +1845,67 @@ mod test {
|
||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
async fn room_search_all() {
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"GET",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/publicRooms".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/public_rooms.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let client = Client::new(homeserver).unwrap();
|
||||||
|
|
||||||
|
if let get_public_rooms::Response { chunk, .. } = client
|
||||||
|
// .get_public_rooms(Some(10), None, Some(&mockito::server_url().to_string()))
|
||||||
|
.get_public_rooms(Some(10), None, None)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
assert_eq!(chunk.len(), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[allow(irrefutable_let_patterns)]
|
||||||
|
async fn room_search_filtered() {
|
||||||
|
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
|
||||||
|
let user = UserId::try_from("@example:localhost").unwrap();
|
||||||
|
|
||||||
|
let session = Session {
|
||||||
|
access_token: "1234".to_owned(),
|
||||||
|
user_id: user.clone(),
|
||||||
|
device_id: "DEVICEID".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let _m = mock(
|
||||||
|
"POST",
|
||||||
|
Matcher::Regex(r"^/_matrix/client/r0/publicRooms".to_string()),
|
||||||
|
)
|
||||||
|
.with_status(200)
|
||||||
|
.with_body_from_file("../test_data/public_rooms.json")
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let client = Client::new(homeserver).unwrap();
|
||||||
|
client.restore_login(session).await.unwrap();
|
||||||
|
|
||||||
|
let generic_search_term = Some("cheese".to_string());
|
||||||
|
let mut request = RoomSearchBuilder::default();
|
||||||
|
request.filter(Filter {
|
||||||
|
generic_search_term,
|
||||||
|
});
|
||||||
|
|
||||||
|
if let get_public_rooms_filtered::Response { chunk, .. } =
|
||||||
|
client.get_public_rooms_filtered(request).await.unwrap()
|
||||||
|
{
|
||||||
|
assert_eq!(chunk.len(), 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
async fn leave_room() {
|
async fn leave_room() {
|
||||||
|
|
|
@ -52,7 +52,9 @@ mod error;
|
||||||
mod request_builder;
|
mod request_builder;
|
||||||
pub use client::{Client, ClientConfig, SyncSettings};
|
pub use client::{Client, ClientConfig, SyncSettings};
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use request_builder::{MessagesRequestBuilder, RegistrationBuilder, RoomBuilder};
|
pub use request_builder::{
|
||||||
|
MessagesRequestBuilder, RegistrationBuilder, RoomBuilder, RoomSearchBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::events::EventJson;
|
||||||
use crate::identifiers::{DeviceId, RoomId, UserId};
|
use crate::identifiers::{DeviceId, RoomId, UserId};
|
||||||
use api::r0::account::register;
|
use api::r0::account::register;
|
||||||
use api::r0::account::register::RegistrationKind;
|
use api::r0::account::register::RegistrationKind;
|
||||||
|
use api::r0::directory::get_public_rooms_filtered::{self, Filter, RoomNetwork};
|
||||||
use api::r0::filter::RoomEventFilter;
|
use api::r0::filter::RoomEventFilter;
|
||||||
use api::r0::membership::Invite3pid;
|
use api::r0::membership::Invite3pid;
|
||||||
use api::r0::message::get_message_events::{self, Direction};
|
use api::r0::message::get_message_events::{self, Direction};
|
||||||
|
@ -405,6 +406,92 @@ impl Into<register::Request> for RegistrationBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a builder for making get_message_event requests.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// # use std::convert::TryFrom;
|
||||||
|
/// # use matrix_sdk::{Client, RoomSearchBuilder};
|
||||||
|
/// # use matrix_sdk::api::r0::directory::get_public_rooms_filtered::{self, RoomNetwork, Filter};
|
||||||
|
/// # use url::Url;
|
||||||
|
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||||
|
/// # let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
/// # rt.block_on(async {
|
||||||
|
/// # let last_sync_token = "".to_string();
|
||||||
|
/// let mut client = Client::new(homeserver).unwrap();
|
||||||
|
///
|
||||||
|
/// let generic_search_term = Some("matrix-rust-sdk".to_string());
|
||||||
|
/// let mut builder = RoomSearchBuilder::new();
|
||||||
|
/// builder
|
||||||
|
/// .filter(Filter { generic_search_term, })
|
||||||
|
/// .since(last_sync_token)
|
||||||
|
/// .room_network(RoomNetwork::Matrix);
|
||||||
|
///
|
||||||
|
/// client.get_public_rooms_filtered(builder).await.is_err();
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct RoomSearchBuilder {
|
||||||
|
server: Option<String>,
|
||||||
|
limit: Option<UInt>,
|
||||||
|
since: Option<String>,
|
||||||
|
filter: Option<Filter>,
|
||||||
|
room_network: Option<RoomNetwork>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RoomSearchBuilder {
|
||||||
|
/// Create a `RoomSearchBuilder` builder to make a `get_message_events::Request`.
|
||||||
|
///
|
||||||
|
/// The `room_id` and `from`` fields **need to be set** to create the request.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The server to fetch the public room lists from.
|
||||||
|
///
|
||||||
|
/// `None` means the server this request is sent to.
|
||||||
|
pub fn server(&mut self, server: String) -> &mut Self {
|
||||||
|
self.server = Some(server);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Limit for the number of results to return.
|
||||||
|
pub fn limit(&mut self, limit: UInt) -> &mut Self {
|
||||||
|
self.limit = Some(limit);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pagination token from a previous request.
|
||||||
|
pub fn since(&mut self, since: String) -> &mut Self {
|
||||||
|
self.since = Some(since);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Filter to apply to the results.
|
||||||
|
pub fn filter(&mut self, filter: Filter) -> &mut Self {
|
||||||
|
self.filter = Some(filter);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Network to fetch the public room lists from.
|
||||||
|
pub fn room_network(&mut self, room_network: RoomNetwork) -> &mut Self {
|
||||||
|
self.room_network = Some(room_network);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<get_public_rooms_filtered::Request> for RoomSearchBuilder {
|
||||||
|
fn into(self) -> get_public_rooms_filtered::Request {
|
||||||
|
get_public_rooms_filtered::Request {
|
||||||
|
room_network: self.room_network.unwrap_or_default(),
|
||||||
|
limit: self.limit,
|
||||||
|
server: self.server,
|
||||||
|
since: self.since,
|
||||||
|
filter: self.filter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"chunk": [
|
||||||
|
{
|
||||||
|
"aliases": [
|
||||||
|
"#murrays:cheese.bar"
|
||||||
|
],
|
||||||
|
"avatar_url": "mxc://bleeker.street/CHEDDARandBRIE",
|
||||||
|
"guest_can_join": false,
|
||||||
|
"name": "CHEESE",
|
||||||
|
"num_joined_members": 37,
|
||||||
|
"room_id": "!ol19s:bleecker.street",
|
||||||
|
"topic": "Tasty tasty cheese",
|
||||||
|
"world_readable": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"next_batch": "p190q",
|
||||||
|
"prev_batch": "p1902",
|
||||||
|
"total_room_count_estimate": 115
|
||||||
|
}
|
Loading…
Reference in New Issue