Skip to content

Commit d4b779a

Browse files
committed
Implement new MSC4143 endpoint
1 parent 30d063c commit d4b779a

6 files changed

Lines changed: 228 additions & 191 deletions

File tree

crates/ruma-client-api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ unstable-msc4140 = ["ruma-common/unstable-msc4140"]
5353
unstable-msc4143 = []
5454
unstable-msc4186 = ["ruma-common/unstable-msc4186"]
5555
unstable-msc4191 = []
56+
unstable-msc4195 = ["unstable-msc4143"]
5657
unstable-msc4222 = []
5758
# Thread subscription support.
5859
unstable-msc4306 = []

crates/ruma-client-api/src/discovery/discover_homeserver.rs

Lines changed: 3 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,14 @@
44
//!
55
//! Get discovery information about the domain.
66
7-
#[cfg(feature = "unstable-msc4143")]
8-
use std::borrow::Cow;
9-
10-
#[cfg(feature = "unstable-msc4143")]
11-
use ruma_common::serde::JsonObject;
127
use ruma_common::{
138
api::{request, response, Metadata},
149
metadata,
1510
};
16-
#[cfg(feature = "unstable-msc4143")]
17-
use serde::de::DeserializeOwned;
1811
use serde::{Deserialize, Serialize};
12+
1913
#[cfg(feature = "unstable-msc4143")]
20-
use serde_json::Value as JsonValue;
14+
use crate::rtc::RtcTransport;
2115

2216
const METADATA: Metadata = metadata! {
2317
method: GET,
@@ -61,7 +55,7 @@ pub struct Response {
6155
default,
6256
skip_serializing_if = "Vec::is_empty"
6357
)]
64-
pub rtc_foci: Vec<RtcFocusInfo>,
58+
pub rtc_foci: Vec<RtcTransport>,
6559
}
6660

6761
impl Request {
@@ -133,185 +127,3 @@ impl TileServerInfo {
133127
Self { map_style_url }
134128
}
135129
}
136-
137-
/// Information about a specific MatrixRTC focus.
138-
#[cfg(feature = "unstable-msc4143")]
139-
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
140-
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
141-
#[serde(tag = "type")]
142-
pub enum RtcFocusInfo {
143-
/// A LiveKit RTC focus.
144-
#[serde(rename = "livekit")]
145-
LiveKit(LiveKitRtcFocusInfo),
146-
147-
/// A custom RTC focus.
148-
#[doc(hidden)]
149-
#[serde(untagged)]
150-
_Custom(CustomRtcFocusInfo),
151-
}
152-
153-
#[cfg(feature = "unstable-msc4143")]
154-
impl RtcFocusInfo {
155-
/// A constructor to create a custom RTC focus.
156-
///
157-
/// Prefer to use the public variants of `RtcFocusInfo` where possible; this constructor is
158-
/// meant to be used for unsupported focus types only and does not allow setting arbitrary data
159-
/// for supported ones.
160-
///
161-
/// # Errors
162-
///
163-
/// Returns an error if the `focus_type` is known and serialization of `data` to the
164-
/// corresponding `RtcFocusInfo` variant fails.
165-
pub fn new(focus_type: &str, data: JsonObject) -> serde_json::Result<Self> {
166-
fn deserialize_variant<T: DeserializeOwned>(obj: JsonObject) -> serde_json::Result<T> {
167-
serde_json::from_value(JsonValue::Object(obj))
168-
}
169-
170-
Ok(match focus_type {
171-
"livekit" => Self::LiveKit(deserialize_variant(data)?),
172-
_ => Self::_Custom(CustomRtcFocusInfo { focus_type: focus_type.to_owned(), data }),
173-
})
174-
}
175-
176-
/// Creates a new `RtcFocusInfo::LiveKit`.
177-
pub fn livekit(service_url: String) -> Self {
178-
Self::LiveKit(LiveKitRtcFocusInfo { service_url })
179-
}
180-
181-
/// Returns a reference to the focus type of this RTC focus.
182-
pub fn focus_type(&self) -> &str {
183-
match self {
184-
Self::LiveKit(_) => "livekit",
185-
Self::_Custom(custom) => &custom.focus_type,
186-
}
187-
}
188-
189-
/// Returns the associated data.
190-
///
191-
/// The returned JSON object won't contain the `focus_type` field, please use
192-
/// [`.focus_type()`][Self::focus_type] to access that.
193-
///
194-
/// Prefer to use the public variants of `RtcFocusInfo` where possible; this method is meant to
195-
/// be used for custom focus types only.
196-
pub fn data(&self) -> Cow<'_, JsonObject> {
197-
fn serialize<T: Serialize>(object: &T) -> JsonObject {
198-
match serde_json::to_value(object).expect("rtc focus type serialization to succeed") {
199-
JsonValue::Object(object) => object,
200-
_ => panic!("all rtc focus types must serialize to objects"),
201-
}
202-
}
203-
204-
match self {
205-
Self::LiveKit(info) => Cow::Owned(serialize(info)),
206-
Self::_Custom(info) => Cow::Borrowed(&info.data),
207-
}
208-
}
209-
}
210-
211-
/// Information about a LiveKit RTC focus.
212-
#[cfg(feature = "unstable-msc4143")]
213-
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
214-
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
215-
pub struct LiveKitRtcFocusInfo {
216-
/// The URL for the LiveKit service.
217-
#[serde(rename = "livekit_service_url")]
218-
pub service_url: String,
219-
}
220-
221-
/// Information about a custom RTC focus type.
222-
#[doc(hidden)]
223-
#[cfg(feature = "unstable-msc4143")]
224-
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
225-
pub struct CustomRtcFocusInfo {
226-
/// The type of RTC focus.
227-
#[serde(rename = "type")]
228-
focus_type: String,
229-
230-
/// Remaining RTC focus data.
231-
#[serde(flatten)]
232-
data: JsonObject,
233-
}
234-
235-
#[cfg(test)]
236-
mod tests {
237-
#[cfg(feature = "unstable-msc4143")]
238-
use assert_matches2::assert_matches;
239-
#[cfg(feature = "unstable-msc4143")]
240-
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
241-
242-
#[cfg(feature = "unstable-msc4143")]
243-
use super::RtcFocusInfo;
244-
245-
#[test]
246-
#[cfg(feature = "unstable-msc4143")]
247-
fn test_livekit_rtc_focus_deserialization() {
248-
// Given the JSON for a LiveKit RTC focus.
249-
let json = json!({
250-
"type": "livekit",
251-
"livekit_service_url": "https://livekit.example.com"
252-
});
253-
254-
// When deserializing it into an RtcFocusInfo.
255-
let focus: RtcFocusInfo = from_json_value(json).unwrap();
256-
257-
// Then it should be recognized as a LiveKit focus with the correct service URL.
258-
assert_matches!(focus, RtcFocusInfo::LiveKit(info));
259-
assert_eq!(info.service_url, "https://livekit.example.com");
260-
}
261-
262-
#[test]
263-
#[cfg(feature = "unstable-msc4143")]
264-
fn test_livekit_rtc_focus_serialization() {
265-
// Given a LiveKit RTC focus info.
266-
let focus = RtcFocusInfo::livekit("https://livekit.example.com".to_owned());
267-
268-
// When serializing it to JSON.
269-
let json = to_json_value(&focus).unwrap();
270-
271-
// Then it should match the expected JSON structure.
272-
assert_eq!(
273-
json,
274-
json!({
275-
"type": "livekit",
276-
"livekit_service_url": "https://livekit.example.com"
277-
})
278-
);
279-
}
280-
281-
#[test]
282-
#[cfg(feature = "unstable-msc4143")]
283-
fn test_custom_rtc_focus_serialization() {
284-
// Given the JSON for a custom RTC focus type with additional fields.
285-
let json = json!({
286-
"type": "some-focus-type",
287-
"additional-type-specific-field": "https://my_focus.domain",
288-
"another-additional-type-specific-field": ["with", "Array", "type"]
289-
});
290-
291-
// When deserializing it into an RtcFocusInfo.
292-
let focus: RtcFocusInfo = from_json_value(json.clone()).unwrap();
293-
294-
// Then it should be recognized as a custom focus type, with all the additional fields
295-
// included.
296-
assert_eq!(focus.focus_type(), "some-focus-type");
297-
298-
let data = &focus.data();
299-
assert_eq!(data["additional-type-specific-field"], "https://my_focus.domain");
300-
301-
let array_values: Vec<&str> = data["another-additional-type-specific-field"]
302-
.as_array()
303-
.unwrap()
304-
.iter()
305-
.map(|v| v.as_str().unwrap())
306-
.collect();
307-
assert_eq!(array_values, vec!["with", "Array", "type"]);
308-
309-
assert!(!data.contains_key("type"));
310-
311-
// When serializing it back to JSON.
312-
let serialized = to_json_value(&focus).unwrap();
313-
314-
// Then it should match the original JSON.
315-
assert_eq!(serialized, json);
316-
}
317-
}

crates/ruma-client-api/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub mod relations;
4343
pub mod rendezvous;
4444
pub mod reporting;
4545
pub mod room;
46+
#[cfg(feature = "unstable-msc4143")]
47+
pub mod rtc;
4648
pub mod search;
4749
pub mod server;
4850
pub mod session;

0 commit comments

Comments
 (0)