Use shared directory types from ruma-common in ruma-federation-api and ruma-client-api
This commit is contained in:
parent
90af430d6b
commit
eaf3fd41cc
@ -54,6 +54,8 @@ Breaking changes:
|
|||||||
`ruma_identifiers::{DeviceKeyId, DeviceKeyAlgorithm}`, respectively
|
`ruma_identifiers::{DeviceKeyId, DeviceKeyAlgorithm}`, respectively
|
||||||
* Use `ruma_identifiers::{ServerName, ServerKeyId}` in `signatures` fields of
|
* Use `ruma_identifiers::{ServerName, ServerKeyId}` in `signatures` fields of
|
||||||
`r0::room::membership::ThirdPartySigned`.
|
`r0::room::membership::ThirdPartySigned`.
|
||||||
|
* Move `r0::directory::{Filter, PublicRoomsChunk, RoomNetwork}` to
|
||||||
|
the `ruma-common` crate
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
|
use ruma_common::directory::PublicRoomsChunk;
|
||||||
use super::PublicRoomsChunk;
|
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata: {
|
metadata: {
|
||||||
|
@ -1,18 +1,8 @@
|
|||||||
//! [POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-publicrooms)
|
//! [POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-publicrooms)
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use serde::{
|
use ruma_common::directory::{Filter, PublicRoomsChunk, RoomNetwork};
|
||||||
de::{Error as _, MapAccess, Visitor},
|
|
||||||
ser::SerializeStruct,
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
|
|
||||||
use serde_json::Value as JsonValue;
|
|
||||||
|
|
||||||
use super::PublicRoomsChunk;
|
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -65,177 +55,3 @@ ruma_api! {
|
|||||||
|
|
||||||
error: crate::Error
|
error: crate::Error
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A filter for public rooms lists
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct Filter {
|
|
||||||
/// A string to search for in the room metadata, e.g. name, topic, canonical alias etc.
|
|
||||||
#[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, JsonValue>()? {
|
|
||||||
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".into())).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".into())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
Breaking Changes:
|
||||||
|
|
||||||
|
* Replace `directory::get_public_rooms::v1::{PublicRoomsChunk, RoomNetwork}` with types from `ruma_common::directory`
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
* Add endpoints:
|
* Add endpoints:
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
//! [GET /_matrix/federation/v1/publicRooms](https://matrix.org/docs/spec/server_server/r0.1.3#get-matrix-federation-v1-publicrooms)
|
//! [GET /_matrix/federation/v1/publicRooms](https://matrix.org/docs/spec/server_server/r0.1.4#get-matrix-federation-v1-publicrooms)
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use js_int::UInt;
|
use js_int::UInt;
|
||||||
use ruma_api::ruma_api;
|
use ruma_api::ruma_api;
|
||||||
use ruma_identifiers::{RoomAliasId, RoomId};
|
use ruma_common::directory::{PublicRoomsChunk, RoomNetwork};
|
||||||
use serde::{
|
|
||||||
de::{Error as _, MapAccess, Visitor},
|
|
||||||
ser::SerializeStruct,
|
|
||||||
Deserialize, Deserializer, Serialize, Serializer,
|
|
||||||
};
|
|
||||||
|
|
||||||
ruma_api! {
|
ruma_api! {
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -22,14 +15,16 @@ ruma_api! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
/// The maximum number of rooms to return. Default is no limit.
|
/// Limit for the number of results to return.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[ruma_api(query)]
|
#[ruma_api(query)]
|
||||||
pub limit: Option<UInt>,
|
pub limit: Option<UInt>,
|
||||||
|
|
||||||
/// Pagination token from a previous request.
|
/// Pagination token from a previous request.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[ruma_api(query)]
|
#[ruma_api(query)]
|
||||||
pub since: Option<String>,
|
pub since: Option<&'a str>,
|
||||||
|
|
||||||
/// Network to fetch the public room lists from.
|
/// Network to fetch the public room lists from.
|
||||||
#[serde(flatten, skip_serializing_if = "ruma_serde::is_default")]
|
#[serde(flatten, skip_serializing_if = "ruma_serde::is_default")]
|
||||||
#[ruma_api(query)]
|
#[ruma_api(query)]
|
||||||
@ -39,140 +34,16 @@ ruma_api! {
|
|||||||
response: {
|
response: {
|
||||||
/// A paginated chunk of public rooms.
|
/// A paginated chunk of public rooms.
|
||||||
pub chunk: Vec<PublicRoomsChunk>,
|
pub chunk: Vec<PublicRoomsChunk>,
|
||||||
|
|
||||||
/// A pagination token for the response.
|
/// A pagination token for the response.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub next_batch: Option<String>,
|
pub next_batch: Option<String>,
|
||||||
|
|
||||||
/// A pagination token that allows fetching previous results.
|
/// A pagination token that allows fetching previous results.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub prev_batch: Option<String>,
|
pub prev_batch: Option<String>,
|
||||||
|
|
||||||
/// An estimate on the total number of public rooms, if the server has an estimate.
|
/// An estimate on the total number of public rooms, if the server has an estimate.
|
||||||
pub total_room_count_estimate: Option<UInt>,
|
pub total_room_count_estimate: Option<UInt>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A chunk of a room list response, describing one room
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
||||||
pub struct PublicRoomsChunk {
|
|
||||||
/// Aliases of the room.
|
|
||||||
#[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<RoomAliasId>,
|
|
||||||
/// The name of the room, if any.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub name: Option<String>,
|
|
||||||
/// The number of members joined to the room.
|
|
||||||
pub num_joined_members: UInt,
|
|
||||||
/// The ID of the room.
|
|
||||||
pub room_id: RoomId,
|
|
||||||
/// The topic of the room, if any.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub topic: Option<String>,
|
|
||||||
/// Whether the room may be viewed by guest users without joining.
|
|
||||||
pub world_readable: bool,
|
|
||||||
/// Whether guest users may join the room and participate in it.
|
|
||||||
///
|
|
||||||
/// If they can, they will be subject to ordinary power level rules like any other user.
|
|
||||||
pub guest_can_join: bool,
|
|
||||||
/// The URL for the room's avatar, if one is set.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub avatar_url: 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, serde_json::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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user