Skip to main content

moq_native/
connect.rs

1/// Error returned when connection setup fails for a terminal auth reason.
2#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
3#[non_exhaustive]
4pub enum ConnectError {
5	/// The server rejected the credentials (HTTP 401). Retrying with the same
6	/// token will fail again.
7	#[error("unauthorized")]
8	Unauthorized,
9
10	/// The credentials were understood but don't grant access to this path
11	/// (HTTP 403).
12	#[error("forbidden")]
13	Forbidden,
14}
15
16impl ConnectError {
17	/// Only the transports that carry an HTTP status (WebTransport, WebSocket) can
18	/// classify one; qmux over tcp/unix has no such response.
19	#[cfg(any(feature = "noq", feature = "quinn", feature = "quiche", feature = "websocket"))]
20	pub(crate) fn from_status_u16(status: u16) -> Option<Self> {
21		match status {
22			401 => Some(Self::Unauthorized),
23			403 => Some(Self::Forbidden),
24			_ => None,
25		}
26	}
27
28	/// Whether this is an authentication failure, meaning a retry is pointless
29	/// until the credentials change.
30	pub fn is_auth(&self) -> bool {
31		matches!(self, Self::Unauthorized | Self::Forbidden)
32	}
33}
34
35#[cfg(all(
36	test,
37	any(feature = "noq", feature = "quinn", feature = "quiche", feature = "websocket")
38))]
39mod tests {
40	use super::*;
41
42	#[test]
43	fn auth_statuses_are_terminal() {
44		assert_eq!(ConnectError::from_status_u16(401), Some(ConnectError::Unauthorized));
45		assert_eq!(ConnectError::from_status_u16(403), Some(ConnectError::Forbidden));
46	}
47
48	#[test]
49	fn non_auth_statuses_are_not_terminal() {
50		for status in [400, 404, 500] {
51			assert_eq!(ConnectError::from_status_u16(status), None);
52		}
53	}
54}