Update public rooms endpoint
This commit is contained in:
parent
aeb4e237b7
commit
bcc06ddd49
@ -8,6 +8,8 @@ Breaking changes:
|
||||
* Remove `inhibit_login` request field, make `access_token` and `device_id` response fields optional (added in r0.4.0)
|
||||
* Remove deprecated `home_server` response field (removed in r0.4.0)
|
||||
* Add `auth_parameters` to `r0::account::AuthenticationData`
|
||||
* Add `room_network` parameter to `r0::directory::get_public_rooms_filtered` to
|
||||
represent `include_all_networks` and `third_party_instance_id` Matrix fields.
|
||||
|
||||
Improvements:
|
||||
|
||||
|
@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PublicRoomsChunk {
|
||||
/// Aliases of the room.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub aliases: Option<Vec<RoomAliasId>>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub aliases: Vec<RoomAliasId>,
|
||||
/// The canonical alias of the room, if any.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub canonical_alias: Option<String>,
|
||||
|
@ -1,8 +1,15 @@
|
||||
//! [POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-publicrooms)
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_api::ruma_api;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{
|
||||
de::{MapAccess, Visitor},
|
||||
ser::SerializeStruct,
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use serde_json::Value;
|
||||
|
||||
use super::PublicRoomsChunk;
|
||||
|
||||
@ -32,6 +39,9 @@ ruma_api! {
|
||||
/// Filter to apply to the results.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub filter: Option<Filter>,
|
||||
/// Network to fetch the public room lists from.
|
||||
#[serde(flatten, skip_serializing_if = "crate::serde::is_default")]
|
||||
pub room_network: RoomNetwork,
|
||||
}
|
||||
|
||||
response {
|
||||
@ -55,3 +65,181 @@ pub struct Filter {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub generic_search_term: Option<String>,
|
||||
}
|
||||
|
||||
/// Information about which networks/protocols from application services on the
|
||||
/// homeserver from which to request rooms.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum RoomNetwork {
|
||||
/// Return rooms from the Matrix network.
|
||||
Matrix,
|
||||
/// Return rooms from all the networks/protocols the homeserver knows about.
|
||||
All,
|
||||
/// Return rooms from a specific third party network/protocol.
|
||||
ThirdParty(String),
|
||||
}
|
||||
|
||||
impl Default for RoomNetwork {
|
||||
fn default() -> Self {
|
||||
RoomNetwork::Matrix
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for RoomNetwork {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state;
|
||||
match self {
|
||||
Self::Matrix => {
|
||||
state = serializer.serialize_struct("RoomNetwork", 0)?;
|
||||
}
|
||||
Self::All => {
|
||||
state = serializer.serialize_struct("RoomNetwork", 1)?;
|
||||
state.serialize_field("include_all_networks", &true)?;
|
||||
}
|
||||
Self::ThirdParty(network) => {
|
||||
state = serializer.serialize_struct("RoomNetwork", 1)?;
|
||||
state.serialize_field("third_party_instance_id", network)?;
|
||||
}
|
||||
}
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for RoomNetwork {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_map(RoomNetworkVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomNetworkVisitor;
|
||||
impl<'de> Visitor<'de> for RoomNetworkVisitor {
|
||||
type Value = RoomNetwork;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("Network selection")
|
||||
}
|
||||
|
||||
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
let mut include_all_networks = false;
|
||||
let mut third_party_instance_id = None;
|
||||
while let Some((key, value)) = access.next_entry::<String, Value>()? {
|
||||
match key.as_str() {
|
||||
"include_all_networks" => {
|
||||
include_all_networks = match value.as_bool() {
|
||||
Some(b) => b,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
"third_party_instance_id" => {
|
||||
third_party_instance_id = value.as_str().map(|v| v.to_owned())
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
if include_all_networks {
|
||||
if third_party_instance_id.is_none() {
|
||||
Ok(RoomNetwork::All)
|
||||
} else {
|
||||
Err(M::Error::custom(
|
||||
"`include_all_networks = true` and `third_party_instance_id` are mutually exclusive.",
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Ok(match third_party_instance_id {
|
||||
Some(network) => RoomNetwork::ThirdParty(network),
|
||||
None => RoomNetwork::Matrix,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||
|
||||
use super::RoomNetwork;
|
||||
|
||||
#[test]
|
||||
fn test_serialize_matrix_network_only() {
|
||||
let json = json!({});
|
||||
assert_eq!(to_json_value(RoomNetwork::Matrix).unwrap(), json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_matrix_network_only() {
|
||||
let json = json!({ "include_all_networks": false });
|
||||
assert_eq!(
|
||||
from_json_value::<RoomNetwork>(json).unwrap(),
|
||||
RoomNetwork::Matrix
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_default_network_is_empty() {
|
||||
let json = json!({});
|
||||
assert_eq!(to_json_value(RoomNetwork::default()).unwrap(), json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_empty_network_is_default() {
|
||||
let json = json!({});
|
||||
assert_eq!(
|
||||
from_json_value::<RoomNetwork>(json).unwrap(),
|
||||
RoomNetwork::default()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_include_all_networks() {
|
||||
let json = json!({ "include_all_networks": true });
|
||||
assert_eq!(to_json_value(RoomNetwork::All).unwrap(), json);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_include_all_networks() {
|
||||
let json = json!({ "include_all_networks": true });
|
||||
assert_eq!(
|
||||
from_json_value::<RoomNetwork>(json).unwrap(),
|
||||
RoomNetwork::All
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_third_party_network() {
|
||||
let json = json!({ "third_party_instance_id": "freenode" });
|
||||
assert_eq!(
|
||||
to_json_value(RoomNetwork::ThirdParty("freenode".to_string())).unwrap(),
|
||||
json
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_third_party_network() {
|
||||
let json = json!({ "third_party_instance_id": "freenode" });
|
||||
assert_eq!(
|
||||
from_json_value::<RoomNetwork>(json).unwrap(),
|
||||
RoomNetwork::ThirdParty("freenode".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deserialize_include_all_networks_and_third_party_exclusivity() {
|
||||
let json = json!({ "include_all_networks": true, "third_party_instance_id": "freenode" });
|
||||
assert_eq!(
|
||||
from_json_value::<RoomNetwork>(json)
|
||||
.unwrap_err()
|
||||
.to_string()
|
||||
.as_str(),
|
||||
"`include_all_networks = true` and `third_party_instance_id` are mutually exclusive."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user