events: Use a string for SessionDescription's type
A clarification in MSC2746 / Matrix 1.7 explains that the `type` field should not be validated but passed as-is to the WebRTC API. It also avoids an unnecessary conversion between the WebRTC API and the Ruma type.
This commit is contained in:
parent
60ed2c7b9a
commit
3f28f2a6f1
@ -13,6 +13,11 @@ Breaking changes:
|
||||
- Remove the `DontNotify` and `Coalesce` variants of `push::Action` according to MSC3987
|
||||
- Old push rules will still deserialize successfully but the `Coalesce` variant will not return
|
||||
`true` for `Action::should_notify()` anymore
|
||||
- Remove `AnswerSessionDescription` and `OfferSessionDescription` types, use `SessionDescription`
|
||||
instead.
|
||||
- Remove `SessionDescriptionType`, use a `String` instead. A clarification in MSC2746 / Matrix 1.7
|
||||
explains that the `type` field should not be validated but passed as-is to the WebRTC API. It
|
||||
also avoids an unnecessary conversion between the WebRTC API and the Ruma type.
|
||||
|
||||
Improvements:
|
||||
|
||||
|
@ -15,8 +15,6 @@ pub mod select_answer;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{serde::StringEnum, PrivOwnedStr};
|
||||
|
||||
/// A VoIP session description.
|
||||
///
|
||||
/// This is the same type as WebRTC's [`RTCSessionDescriptionInit`].
|
||||
@ -26,8 +24,10 @@ use crate::{serde::StringEnum, PrivOwnedStr};
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct SessionDescription {
|
||||
/// The type of session description.
|
||||
///
|
||||
/// This is the `type` field of `RTCSessionDescriptionInit`.
|
||||
#[serde(rename = "type")]
|
||||
pub session_type: SessionDescriptionType,
|
||||
pub session_type: String,
|
||||
|
||||
/// The SDP text of the session description.
|
||||
///
|
||||
@ -39,73 +39,11 @@ pub struct SessionDescription {
|
||||
|
||||
impl SessionDescription {
|
||||
/// Creates a new `SessionDescription` with the given session type and SDP text.
|
||||
pub fn new(session_type: SessionDescriptionType, sdp: String) -> Self {
|
||||
pub fn new(session_type: String, sdp: String) -> Self {
|
||||
Self { session_type, sdp }
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of VoIP session description.
|
||||
///
|
||||
/// This is the same type as WebRTC's [`RTCSdpType`].
|
||||
///
|
||||
/// [`RTCSdpType`]: (https://www.w3.org/TR/webrtc/#dom-rtcsdptype):
|
||||
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
|
||||
#[derive(Clone, PartialEq, Eq, StringEnum)]
|
||||
#[ruma_enum(rename_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum SessionDescriptionType {
|
||||
/// The description must be treated as an SDP final answer, and the offer-answer exchange must
|
||||
/// be considered complete.
|
||||
Answer,
|
||||
|
||||
/// The description must be treated as an SDP offer.
|
||||
Offer,
|
||||
|
||||
/// The description must be treated as an SDP answer, but not final.
|
||||
#[cfg(feature = "unstable-msc2746")]
|
||||
PrAnswer,
|
||||
|
||||
/// The description must be treated as cancelling the current SDP negotiation and moving the
|
||||
/// SDP offer back to what it was in the previous stable state.
|
||||
#[cfg(feature = "unstable-msc2746")]
|
||||
Rollback,
|
||||
|
||||
#[doc(hidden)]
|
||||
_Custom(PrivOwnedStr),
|
||||
}
|
||||
|
||||
/// A VoIP answer session description.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
#[serde(tag = "type", rename = "answer")]
|
||||
pub struct AnswerSessionDescription {
|
||||
/// The SDP text of the session description.
|
||||
pub sdp: String,
|
||||
}
|
||||
|
||||
impl AnswerSessionDescription {
|
||||
/// Creates a new `AnswerSessionDescription` with the given SDP text.
|
||||
pub fn new(sdp: String) -> Self {
|
||||
Self { sdp }
|
||||
}
|
||||
}
|
||||
|
||||
/// A VoIP offer session description.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
#[serde(tag = "type", rename = "offer")]
|
||||
pub struct OfferSessionDescription {
|
||||
/// The SDP text of the session description.
|
||||
pub sdp: String,
|
||||
}
|
||||
|
||||
impl OfferSessionDescription {
|
||||
/// Creates a new `OfferSessionDescription` with the given SDP text.
|
||||
pub fn new(sdp: String) -> Self {
|
||||
Self { sdp }
|
||||
}
|
||||
}
|
||||
|
||||
/// The capabilities of a client in a VoIP call.
|
||||
#[cfg(feature = "unstable-msc2747")]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
|
@ -5,9 +5,9 @@
|
||||
use ruma_macros::EventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::AnswerSessionDescription;
|
||||
#[cfg(feature = "unstable-msc2747")]
|
||||
use super::CallCapabilities;
|
||||
use super::SessionDescription;
|
||||
use crate::{OwnedVoipId, VoipVersionId};
|
||||
|
||||
/// The content of an `m.call.answer` event.
|
||||
@ -18,7 +18,7 @@ use crate::{OwnedVoipId, VoipVersionId};
|
||||
#[ruma_event(type = "m.call.answer", kind = MessageLike)]
|
||||
pub struct CallAnswerEventContent {
|
||||
/// The VoIP session description object.
|
||||
pub answer: AnswerSessionDescription,
|
||||
pub answer: SessionDescription,
|
||||
|
||||
/// A unique identifier for the call.
|
||||
pub call_id: OwnedVoipId,
|
||||
@ -39,11 +39,7 @@ pub struct CallAnswerEventContent {
|
||||
|
||||
impl CallAnswerEventContent {
|
||||
/// Creates an `CallAnswerEventContent` with the given answer, call ID and VoIP version.
|
||||
pub fn new(
|
||||
answer: AnswerSessionDescription,
|
||||
call_id: OwnedVoipId,
|
||||
version: VoipVersionId,
|
||||
) -> Self {
|
||||
pub fn new(answer: SessionDescription, call_id: OwnedVoipId, version: VoipVersionId) -> Self {
|
||||
Self {
|
||||
answer,
|
||||
call_id,
|
||||
@ -57,7 +53,7 @@ impl CallAnswerEventContent {
|
||||
|
||||
/// Convenience method to create a VoIP version 0 `CallAnswerEventContent` with all the required
|
||||
/// fields.
|
||||
pub fn version_0(answer: AnswerSessionDescription, call_id: OwnedVoipId) -> Self {
|
||||
pub fn version_0(answer: SessionDescription, call_id: OwnedVoipId) -> Self {
|
||||
Self::new(answer, call_id, VoipVersionId::V0)
|
||||
}
|
||||
|
||||
@ -65,7 +61,7 @@ impl CallAnswerEventContent {
|
||||
/// fields.
|
||||
#[cfg(feature = "unstable-msc2746")]
|
||||
pub fn version_1(
|
||||
answer: AnswerSessionDescription,
|
||||
answer: SessionDescription,
|
||||
call_id: OwnedVoipId,
|
||||
party_id: OwnedVoipId,
|
||||
) -> Self {
|
||||
|
@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg(feature = "unstable-msc2747")]
|
||||
use super::CallCapabilities;
|
||||
use super::OfferSessionDescription;
|
||||
use super::SessionDescription;
|
||||
#[cfg(feature = "unstable-msc2746")]
|
||||
use crate::OwnedUserId;
|
||||
use crate::{OwnedVoipId, VoipVersionId};
|
||||
@ -35,7 +35,7 @@ pub struct CallInviteEventContent {
|
||||
pub lifetime: UInt,
|
||||
|
||||
/// The session description object.
|
||||
pub offer: OfferSessionDescription,
|
||||
pub offer: SessionDescription,
|
||||
|
||||
/// The version of the VoIP specification this messages adheres to.
|
||||
pub version: VoipVersionId,
|
||||
@ -61,7 +61,7 @@ impl CallInviteEventContent {
|
||||
pub fn new(
|
||||
call_id: OwnedVoipId,
|
||||
lifetime: UInt,
|
||||
offer: OfferSessionDescription,
|
||||
offer: SessionDescription,
|
||||
version: VoipVersionId,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -80,7 +80,7 @@ impl CallInviteEventContent {
|
||||
|
||||
/// Convenience method to create a version 0 `CallInviteEventContent` with all the required
|
||||
/// fields.
|
||||
pub fn version_0(call_id: OwnedVoipId, lifetime: UInt, offer: OfferSessionDescription) -> Self {
|
||||
pub fn version_0(call_id: OwnedVoipId, lifetime: UInt, offer: SessionDescription) -> Self {
|
||||
Self::new(call_id, lifetime, offer, VoipVersionId::V0)
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ impl CallInviteEventContent {
|
||||
call_id: OwnedVoipId,
|
||||
party_id: OwnedVoipId,
|
||||
lifetime: UInt,
|
||||
offer: OfferSessionDescription,
|
||||
offer: SessionDescription,
|
||||
) -> Self {
|
||||
Self {
|
||||
call_id,
|
||||
|
@ -8,7 +8,7 @@ use ruma_common::{
|
||||
candidates::{CallCandidatesEventContent, Candidate},
|
||||
hangup::CallHangupEventContent,
|
||||
invite::CallInviteEventContent,
|
||||
AnswerSessionDescription, OfferSessionDescription,
|
||||
SessionDescription,
|
||||
},
|
||||
AnyMessageLikeEvent, AnySyncMessageLikeEvent, MessageLikeEvent,
|
||||
},
|
||||
@ -21,7 +21,7 @@ use serde_json::{from_value as from_json_value, json, to_value as to_json_value}
|
||||
#[test]
|
||||
fn answer_content_serialization() {
|
||||
let event_content = CallAnswerEventContent::version_0(
|
||||
AnswerSessionDescription::new("not a real sdp".to_owned()),
|
||||
SessionDescription::new("answer".to_owned(), "not a real sdp".to_owned()),
|
||||
"abcdef".into(),
|
||||
);
|
||||
|
||||
@ -51,6 +51,7 @@ fn answer_content_deserialization() {
|
||||
|
||||
let content = from_json_value::<CallAnswerEventContent>(json_data).unwrap();
|
||||
|
||||
assert_eq!(content.answer.session_type, "answer");
|
||||
assert_eq!(content.answer.sdp, "Hello");
|
||||
assert_eq!(content.call_id, "foofoo");
|
||||
assert_eq!(content.version, VoipVersionId::V0);
|
||||
@ -85,6 +86,7 @@ fn answer_event_deserialization() {
|
||||
assert!(message_event.unsigned.is_empty());
|
||||
|
||||
let content = message_event.content;
|
||||
assert_eq!(content.answer.session_type, "answer");
|
||||
assert_eq!(content.answer.sdp, "Hello");
|
||||
assert_eq!(content.call_id, "foofoo");
|
||||
assert_eq!(content.version, VoipVersionId::V0);
|
||||
@ -131,7 +133,7 @@ fn invite_content_serialization() {
|
||||
let event_content = CallInviteEventContent::version_0(
|
||||
"abcdef".into(),
|
||||
uint!(30000),
|
||||
OfferSessionDescription::new("not a real sdp".to_owned()),
|
||||
SessionDescription::new("offer".to_owned(), "not a real sdp".to_owned()),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -203,8 +205,7 @@ mod msc2746 {
|
||||
negotiate::CallNegotiateEventContent,
|
||||
reject::CallRejectEventContent,
|
||||
select_answer::CallSelectAnswerEventContent,
|
||||
AnswerSessionDescription, OfferSessionDescription, SessionDescription,
|
||||
SessionDescriptionType,
|
||||
SessionDescription,
|
||||
},
|
||||
AnyMessageLikeEvent, MessageLikeEvent,
|
||||
},
|
||||
@ -218,7 +219,7 @@ mod msc2746 {
|
||||
"abcdef".into(),
|
||||
"9876".into(),
|
||||
uint!(60000),
|
||||
OfferSessionDescription::new("not a real sdp".to_owned()),
|
||||
SessionDescription::new("offer".to_owned(), "not a real sdp".to_owned()),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -266,13 +267,14 @@ mod msc2746 {
|
||||
assert_eq!(content.party_id.unwrap(), "9876");
|
||||
assert_eq!(content.lifetime, uint!(60000));
|
||||
assert_eq!(content.version, VoipVersionId::V1);
|
||||
assert_eq!(content.offer.session_type, "offer");
|
||||
assert_eq!(content.offer.sdp, "not a real sdp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn answer_event_serialization() {
|
||||
let content = CallAnswerEventContent::version_1(
|
||||
AnswerSessionDescription::new("not a real sdp".to_owned()),
|
||||
SessionDescription::new("answer".to_owned(), "not a real sdp".to_owned()),
|
||||
"abcdef".into(),
|
||||
"9876".into(),
|
||||
);
|
||||
@ -296,7 +298,7 @@ mod msc2746 {
|
||||
fn answer_event_capabilities_serialization() {
|
||||
let content = assign!(
|
||||
CallAnswerEventContent::version_1(
|
||||
AnswerSessionDescription::new("not a real sdp".to_owned()),
|
||||
SessionDescription::new("answer".to_owned(), "not a real sdp".to_owned()),
|
||||
"abcdef".into(),
|
||||
"9876".into()
|
||||
),
|
||||
@ -353,6 +355,7 @@ mod msc2746 {
|
||||
assert_eq!(content.call_id, "abcdef");
|
||||
assert_eq!(content.party_id.unwrap(), "9876");
|
||||
assert_eq!(content.version.as_ref(), "org.matrix.1b");
|
||||
assert_eq!(content.answer.session_type, "answer");
|
||||
assert_eq!(content.answer.sdp, "not a real sdp");
|
||||
#[cfg(feature = "unstable-msc2747")]
|
||||
assert!(content.capabilities.dtmf);
|
||||
@ -485,7 +488,7 @@ mod msc2746 {
|
||||
"abcdef".into(),
|
||||
"9876".into(),
|
||||
uint!(30000),
|
||||
SessionDescription::new(SessionDescriptionType::Offer, "not a real sdp".to_owned()),
|
||||
SessionDescription::new("offer".to_owned(), "not a real sdp".to_owned()),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
@ -512,7 +515,7 @@ mod msc2746 {
|
||||
"version": "1",
|
||||
"lifetime": 30000,
|
||||
"description": {
|
||||
"type": "pranswer",
|
||||
"type": "answer",
|
||||
"sdp": "not a real sdp",
|
||||
}
|
||||
},
|
||||
@ -532,7 +535,7 @@ mod msc2746 {
|
||||
assert_eq!(content.call_id, "abcdef");
|
||||
assert_eq!(content.party_id, "9876");
|
||||
assert_eq!(content.lifetime, uint!(30000));
|
||||
assert_eq!(content.description.session_type, SessionDescriptionType::PrAnswer);
|
||||
assert_eq!(content.description.session_type, "answer");
|
||||
assert_eq!(content.description.sdp, "not a real sdp");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user