1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! Modules for events in the `m.call` namespace.
//!
//! This module also contains types shared by events in its child namespaces.

pub mod answer;
pub mod candidates;
pub mod hangup;
pub mod invite;
#[cfg(feature = "unstable-msc3401")]
pub mod member;
pub mod negotiate;
#[cfg(feature = "unstable-msc4075")]
pub mod notify;
pub mod reject;
#[cfg(feature = "unstable-msc3291")]
pub mod sdp_stream_metadata_changed;
pub mod select_answer;

use ruma_macros::StringEnum;
use serde::{Deserialize, Serialize};

use crate::PrivOwnedStr;

/// A VoIP session description.
///
/// This is the same type as WebRTC's [`RTCSessionDescriptionInit`].
///
/// [`RTCSessionDescriptionInit`]: (https://www.w3.org/TR/webrtc/#dom-rtcsessiondescriptioninit):
#[derive(Clone, Debug, Deserialize, Serialize)]
#[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: String,

    /// The SDP text of the session description.
    ///
    /// Defaults to an empty string.
    #[serde(default)]
    pub sdp: String,
}

impl SessionDescription {
    /// Creates a new `SessionDescription` with the given session type and SDP text.
    pub fn new(session_type: String, sdp: String) -> Self {
        Self { session_type, sdp }
    }
}

/// Metadata about a VoIP stream.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct StreamMetadata {
    /// The purpose of the stream.
    pub purpose: StreamPurpose,

    /// Whether the audio track of the stream is muted.
    ///
    /// Defaults to `false`.
    #[cfg(feature = "unstable-msc3291")]
    #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
    pub audio_muted: bool,

    /// Whether the video track of the stream is muted.
    ///
    /// Defaults to `false`.
    #[cfg(feature = "unstable-msc3291")]
    #[serde(default, skip_serializing_if = "ruma_common::serde::is_default")]
    pub video_muted: bool,
}

impl StreamMetadata {
    /// Creates a new `StreamMetadata` with the given purpose.
    pub fn new(purpose: StreamPurpose) -> Self {
        Self {
            purpose,
            #[cfg(feature = "unstable-msc3291")]
            audio_muted: false,
            #[cfg(feature = "unstable-msc3291")]
            video_muted: false,
        }
    }
}

/// The purpose of a VoIP stream.
#[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
#[derive(Clone, PartialEq, Eq, StringEnum)]
#[ruma_enum(rename_all = "m.lowercase")]
#[non_exhaustive]
pub enum StreamPurpose {
    /// `m.usermedia`.
    ///
    /// A stream that contains the webcam and/or microphone tracks.
    UserMedia,

    /// `m.screenshare`.
    ///
    /// A stream with the screen-sharing tracks.
    ScreenShare,

    #[doc(hidden)]
    _Custom(PrivOwnedStr),
}

/// The capabilities of a client in a VoIP call.
#[cfg(feature = "unstable-msc2747")]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct CallCapabilities {
    /// Whether this client supports [DTMF].
    ///
    /// Defaults to `false`.
    ///
    /// [DTMF]: https://w3c.github.io/webrtc-pc/#peer-to-peer-dtmf
    #[serde(rename = "m.call.dtmf", default)]
    pub dtmf: bool,
}

#[cfg(feature = "unstable-msc2747")]
impl CallCapabilities {
    /// Creates a default `CallCapabilities`.
    pub fn new() -> Self {
        Self::default()
    }

    /// Whether this `CallCapabilities` only contains default values.
    pub fn is_default(&self) -> bool {
        !self.dtmf
    }
}