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
//! Platform-agnostic functionality of [`platform::RtcPeerConnection`].

use derive_more::{Display, From};

use crate::{
    platform::{self, RtcStatsError},
    utils::Caused,
};

/// Representation of [RTCSdpType].
///
/// [RTCSdpType]: https://w3.org/TR/webrtc/#dom-rtcsdptype
#[derive(Debug)]
pub enum SdpType {
    /// [`offer` type][1] of SDP.
    ///
    /// [1]: https://w3.org/TR/webrtc/#dom-rtcsdptype-offer
    Offer(String),

    /// [`answer` type][1] of SDP.
    ///
    /// [1]: https://w3.org/TR/webrtc/#dom-rtcsdptype-answer
    Answer(String),
}

/// [RTCIceCandidate][1] representation.
///
/// [1]: https://w3.org/TR/webrtc/#rtcicecandidate-interface
#[derive(Debug)]
pub struct IceCandidate {
    /// [`candidate` field][2] of the discovered [RTCIceCandidate][1].
    ///
    /// [1]: https://w3.org/TR/webrtc/#dom-rtcicecandidate
    /// [2]: https://w3.org/TR/webrtc/#dom-rtcicecandidate-candidate
    pub candidate: String,

    /// [`sdpMLineIndex` field][2] of the discovered [RTCIceCandidate][1].
    ///
    /// [1]: https://w3.org/TR/webrtc/#dom-rtcicecandidate
    /// [2]: https://w3.org/TR/webrtc/#dom-rtcicecandidate-sdpmlineindex
    pub sdp_m_line_index: Option<u16>,

    /// [`sdpMid` field][2] of the discovered [RTCIceCandidate][1].
    ///
    /// [1]: https://w3.org/TR/webrtc/#dom-rtcicecandidate
    /// [2]: https://w3.org/TR/webrtc/#dom-rtcicecandidate-sdpmid
    pub sdp_mid: Option<String>,
}

/// Errors that may occur during signaling between this and remote
/// [RTCPeerConnection][1] and event handlers setting errors.
///
/// [1]: https://w3.org/TR/webrtc/#dom-rtcpeerconnection
#[derive(Caused, Clone, Debug, Display, From)]
#[cause(error = platform::Error)]
pub enum RtcPeerConnectionError {
    /// Occurs when cannot adds new remote candidate to the
    /// [RTCPeerConnection][1]'s remote description.
    ///
    /// [1]: https://w3.org/TR/webrtc/#dom-rtcpeerconnection
    #[display(fmt = "Failed to add ICE candidate: {}", _0)]
    #[from(ignore)]
    AddIceCandidateFailed(platform::Error),

    /// Occurs when cannot obtains [SDP answer][`SdpType::Answer`] from
    /// the underlying [`platform::RtcPeerConnection`].
    #[display(fmt = "Failed to create SDP answer: {}", _0)]
    #[from(ignore)]
    CreateAnswerFailed(platform::Error),

    /// Occurs when a new [`platform::RtcPeerConnection`] cannot be created.
    #[display(fmt = "Failed to create PeerConnection: {}", _0)]
    #[from(ignore)]
    PeerCreationError(platform::Error),

    /// Occurs when cannot obtains [SDP offer][`SdpType::Offer`] from
    /// the underlying [`platform::RtcPeerConnection`].
    #[display(fmt = "Failed to create SDP offer: {}", _0)]
    #[from(ignore)]
    CreateOfferFailed(platform::Error),

    /// Occurs while getting and parsing [`platform::RtcStats`] of
    /// [`platform::RtcPeerConnection`].
    #[display(fmt = "Failed to get RTCStats: {}", _0)]
    RtcStatsError(#[cause] RtcStatsError),

    /// [PeerConnection.getStats][1] promise thrown exception.
    ///
    /// [1]: https://tinyurl.com/w6hmt5f
    #[display(fmt = "PeerConnection.getStats() failed with error: {}", _0)]
    #[from(ignore)]
    GetStatsException(platform::Error),

    /// Occurs if the local description associated with the
    /// [`platform::RtcPeerConnection`] cannot be changed.
    #[display(fmt = "Failed to set local SDP description: {}", _0)]
    #[from(ignore)]
    SetLocalDescriptionFailed(platform::Error),

    /// Occurs if the description of the remote end of the
    /// [`platform::RtcPeerConnection`] cannot be changed.
    #[display(fmt = "Failed to set remote SDP description: {}", _0)]
    #[from(ignore)]
    SetRemoteDescriptionFailed(platform::Error),
}