diff --git a/src/client.rs b/src/client.rs index 41a813d..5ed89cf 100644 --- a/src/client.rs +++ b/src/client.rs @@ -52,7 +52,7 @@ mod encryption { use std::net::TcpStream; use crate::{ - error::{Error, Result, UrlErrorType}, + error::{Error, Result, UrlError}, stream::Mode, }; @@ -62,7 +62,7 @@ mod encryption { pub fn wrap_stream(stream: TcpStream, _domain: &str, mode: Mode) -> Result { match mode { Mode::Plain => Ok(stream), - Mode::Tls => Err(Error::Url(UrlErrorType::TlsFeatureNotEnabled)), + Mode::Tls => Err(Error::Url(UrlError::TlsFeatureNotEnabled)), } } } @@ -71,7 +71,7 @@ use self::encryption::wrap_stream; pub use self::encryption::AutoStream; use crate::{ - error::{Error, Result, UrlErrorType}, + error::{Error, Result, UrlError}, handshake::{client::ClientHandshake, HandshakeError}, protocol::WebSocket, stream::{Mode, NoDelay}, @@ -103,7 +103,7 @@ pub fn connect_with_config( ) -> Result<(WebSocket, Response)> { let uri = request.uri(); let mode = uri_mode(uri)?; - let host = request.uri().host().ok_or(Error::Url(UrlErrorType::NoHostName))?; + let host = request.uri().host().ok_or(Error::Url(UrlError::NoHostName))?; let port = uri.port_u16().unwrap_or(match mode { Mode::Plain => 80, Mode::Tls => 443, @@ -165,7 +165,7 @@ pub fn connect(request: Req) -> Result<(WebSocket Result { - let domain = uri.host().ok_or(Error::Url(UrlErrorType::NoHostName))?; + let domain = uri.host().ok_or(Error::Url(UrlError::NoHostName))?; for addr in addrs { debug!("Trying to contact {} at {}...", uri, addr); if let Ok(raw_stream) = TcpStream::connect(addr) { @@ -174,7 +174,7 @@ fn connect_to_some(addrs: &[SocketAddr], uri: &Uri, mode: Mode) -> Result Result { match uri.scheme_str() { Some("ws") => Ok(Mode::Plain), Some("wss") => Ok(Mode::Tls), - _ => Err(Error::Url(UrlErrorType::UnsupportedUrlScheme)), + _ => Err(Error::Url(UrlError::UnsupportedUrlScheme)), } } diff --git a/src/error.rs b/src/error.rs index 29a944c..f4dfdf1 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,6 @@ //! Error handling. -use std::{fmt, io, result, str, string}; +use std::{io, result, str, string}; use crate::protocol::{frame::coding::Data, Message}; use http::Response; @@ -44,8 +44,8 @@ pub enum Error { /// underlying connection and you should probably consider them fatal. #[error("IO error: {0}")] Io(#[from] io::Error), - #[cfg(feature = "tls")] /// TLS error. + #[cfg(feature = "tls")] #[error("TLS error: {0}")] Tls(#[from] tls::Error), /// - When reading: buffer capacity exhausted. @@ -59,12 +59,12 @@ pub enum Error { /// Message send queue full. #[error("Send queue is full")] SendQueueFull(Message), - /// UTF coding error + /// UTF coding error. #[error("UTF-8 encoding error")] Utf8, /// Invalid URL. #[error("URL error: {0}")] - Url(UrlErrorType), + Url(UrlError), /// HTTP error. #[error("HTTP error: {}", .0.status())] Http(Response>), @@ -227,31 +227,24 @@ pub enum ProtocolError { } /// Indicates the specific type/cause of URL error. -#[derive(Debug, PartialEq, Eq)] -pub enum UrlErrorType { +#[derive(Error, Debug, PartialEq, Eq)] +pub enum UrlError { /// TLS is used despite not being compiled with the TLS feature enabled. + #[error("TLS support not compiled in")] TlsFeatureNotEnabled, /// The URL does not include a host name. + #[error("No host name in the URL")] NoHostName, /// Failed to connect with this URL. + #[error("Unable to connect to {0}")] UnableToConnect(String), /// Unsupported URL scheme used (only `ws://` or `wss://` may be used). + #[error("URL scheme not supported")] UnsupportedUrlScheme, /// The URL host name, though included, is empty. + #[error("URL contains empty host name")] EmptyHostName, /// The URL does not include a path/query. + #[error("No path/query in URL")] NoPathOrQuery, } - -impl fmt::Display for UrlErrorType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - UrlErrorType::TlsFeatureNotEnabled => write!(f, "TLS support not compiled in"), - UrlErrorType::NoHostName => write!(f, "No host name in the URL"), - UrlErrorType::UnableToConnect(uri) => write!(f, "Unable to connect to {}", uri), - UrlErrorType::UnsupportedUrlScheme => write!(f, "URL scheme not supported"), - UrlErrorType::EmptyHostName => write!(f, "URL contains empty host name"), - UrlErrorType::NoPathOrQuery => write!(f, "No path/query in URL"), - } - } -} diff --git a/src/handshake/client.rs b/src/handshake/client.rs index fc4c579..92e5477 100644 --- a/src/handshake/client.rs +++ b/src/handshake/client.rs @@ -16,7 +16,7 @@ use super::{ HandshakeRole, MidHandshake, ProcessingResult, }; use crate::{ - error::{Error, ProtocolError, Result, UrlErrorType}, + error::{Error, ProtocolError, Result, UrlError}, protocol::{Role, WebSocket, WebSocketConfig}, }; @@ -97,7 +97,7 @@ fn generate_request(request: Request, key: &str) -> Result> { let mut req = Vec::new(); let uri = request.uri(); - let authority = uri.authority().ok_or(Error::Url(UrlErrorType::NoHostName))?.as_str(); + let authority = uri.authority().ok_or(Error::Url(UrlError::NoHostName))?.as_str(); let host = if let Some(idx) = authority.find('@') { // handle possible name:password@ authority.split_at(idx + 1).1 @@ -105,7 +105,7 @@ fn generate_request(request: Request, key: &str) -> Result> { authority }; if authority.is_empty() { - return Err(Error::Url(UrlErrorType::EmptyHostName)); + return Err(Error::Url(UrlError::EmptyHostName)); } write!( @@ -119,7 +119,7 @@ fn generate_request(request: Request, key: &str) -> Result> { Sec-WebSocket-Key: {key}\r\n", version = request.version(), host = host, - path = uri.path_and_query().ok_or(Error::Url(UrlErrorType::NoPathOrQuery))?.as_str(), + path = uri.path_and_query().ok_or(Error::Url(UrlError::NoPathOrQuery))?.as_str(), key = key ) .unwrap();