rtsp/error.rs
1//! Error types for the RTSP server library.
2
3use std::fmt;
4
5/// Errors that can occur in the RTSP server library.
6///
7/// Variants map to specific failure modes across the stack:
8///
9/// - **Protocol**: [`Parse`](Self::Parse) — malformed RTSP messages.
10/// - **Transport**: [`Io`](Self::Io) — socket/network failures.
11/// - **Session**: [`SessionNotFound`](Self::SessionNotFound),
12/// [`SessionNotPlaying`](Self::SessionNotPlaying),
13/// [`TransportNotConfigured`](Self::TransportNotConfigured).
14/// - **Server**: [`NotStarted`](Self::NotStarted),
15/// [`AlreadyRunning`](Self::AlreadyRunning).
16/// - **Mount**: [`MountNotFound`](Self::MountNotFound).
17/// - **Server**: [`InvalidBindAddress`](Self::InvalidBindAddress) — bind address must have an explicit non-zero port.
18#[derive(Debug, thiserror::Error)]
19pub enum RtspError {
20 /// Underlying I/O or socket error.
21 #[error("I/O error: {0}")]
22 Io(#[from] std::io::Error),
23
24 /// Bind address must be `host:port` with an explicit non-zero port (port 0 is not allowed).
25 #[error("invalid bind address: {0}")]
26 InvalidBindAddress(String),
27
28 /// No session with the given ID exists in the [`SessionManager`](crate::session::SessionManager).
29 #[error("session not found: {0}")]
30 SessionNotFound(String),
31
32 /// SETUP has not been completed for this session (no UDP ports negotiated).
33 #[error("transport not configured for session: {0}")]
34 TransportNotConfigured(String),
35
36 /// Attempted to send media to a session that is not in the Playing state.
37 #[error("session not in playing state: {0}")]
38 SessionNotPlaying(String),
39
40 /// [`Server::start`](crate::Server::start) has not been called yet.
41 #[error("server not started")]
42 NotStarted,
43
44 /// [`Server::start`](crate::Server::start) was called while already running.
45 #[error("server already running")]
46 AlreadyRunning,
47
48 /// Failed to parse an RTSP request message (RFC 2326 §6).
49 #[error("RTSP parse error: {kind}")]
50 Parse { kind: ParseErrorKind },
51
52 /// Server-side UDP port allocation exhausted the 5000–65534 range.
53 #[error("port range exhausted (tried to allocate beyond u16 range)")]
54 PortRangeExhausted,
55
56 /// No mount registered at the requested path.
57 #[error("mount not found: {0}")]
58 MountNotFound(String),
59}
60
61/// Specific kind of RTSP parse failure.
62#[derive(Debug)]
63pub enum ParseErrorKind {
64 /// Input was empty (no request line).
65 EmptyRequest,
66 /// Request line did not have the expected `Method URI Version` format.
67 InvalidRequestLine,
68 /// A header line did not contain a colon separator.
69 InvalidHeader,
70}
71
72impl fmt::Display for ParseErrorKind {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match self {
75 Self::EmptyRequest => write!(f, "empty request"),
76 Self::InvalidRequestLine => write!(f, "invalid request line"),
77 Self::InvalidHeader => write!(f, "invalid header"),
78 }
79 }
80}
81
82/// Convenience alias for `Result<T, RtspError>`.
83pub type Result<T> = std::result::Result<T, RtspError>;