#![allow(dead_code)] use std::io; use std::net; use std::num::ParseIntError; use std::string::FromUtf8Error; use thiserror::Error; pub type Result = std::result::Result; #[derive(Error, Debug, PartialEq)] #[non_exhaustive] pub enum Error { #[error("buffer: full")] ErrBufferFull, #[error("buffer: closed")] ErrBufferClosed, #[error("buffer: short")] ErrBufferShort, #[error("packet too big")] ErrPacketTooBig, #[error("i/o timeout")] ErrTimeout, #[error("udp: listener closed")] ErrClosedListener, #[error("udp: listen queue exceeded")] ErrListenQueueExceeded, #[error("udp: listener accept ch closed")] ErrClosedListenerAcceptCh, #[error("obs cannot be nil")] ErrObsCannotBeNil, #[error("se of closed network connection")] ErrUseClosedNetworkConn, #[error("addr is not a net.UDPAddr")] ErrAddrNotUdpAddr, #[error("something went wrong with locAddr")] ErrLocAddr, #[error("already closed")] ErrAlreadyClosed, #[error("no remAddr defined")] ErrNoRemAddr, #[error("address already in use")] ErrAddressAlreadyInUse, #[error("no such UDPConn")] ErrNoSuchUdpConn, #[error("cannot remove unspecified IP by the specified IP")] ErrCannotRemoveUnspecifiedIp, #[error("no address assigned")] ErrNoAddressAssigned, #[error("1:1 NAT requires more than one mapping")] ErrNatRequriesMapping, #[error("length mismtach between mappedIPs and localIPs")] ErrMismatchLengthIp, #[error("non-udp translation is not supported yet")] ErrNonUdpTranslationNotSupported, #[error("no associated local address")] ErrNoAssociatedLocalAddress, #[error("no NAT binding found")] ErrNoNatBindingFound, #[error("has no permission")] ErrHasNoPermission, #[error("host name must not be empty")] ErrHostnameEmpty, #[error("failed to parse IP address")] ErrFailedToParseIpaddr, #[error("no interface is available")] ErrNoInterface, #[error("not found")] ErrNotFound, #[error("unexpected network")] ErrUnexpectedNetwork, #[error("can't assign requested address")] ErrCantAssignRequestedAddr, #[error("unknown network")] ErrUnknownNetwork, #[error("no router linked")] ErrNoRouterLinked, #[error("invalid port number")] ErrInvalidPortNumber, #[error("unexpected type-switch failure")] ErrUnexpectedTypeSwitchFailure, #[error("bind failed")] ErrBindFailed, #[error("end port is less than the start")] ErrEndPortLessThanStart, #[error("port space exhausted")] ErrPortSpaceExhausted, #[error("vnet is not enabled")] ErrVnetDisabled, #[error("invalid local IP in static_ips")] ErrInvalidLocalIpInStaticIps, #[error("mapped in static_ips is beyond subnet")] ErrLocalIpBeyondStaticIpsSubset, #[error("all static_ips must have associated local IPs")] ErrLocalIpNoStaticsIpsAssociated, #[error("router already started")] ErrRouterAlreadyStarted, #[error("router already stopped")] ErrRouterAlreadyStopped, #[error("static IP is beyond subnet")] ErrStaticIpIsBeyondSubnet, #[error("address space exhausted")] ErrAddressSpaceExhausted, #[error("no IP address is assigned for eth0")] ErrNoIpaddrEth0, #[error("Invalid mask")] ErrInvalidMask, #[error("parse ipnet: {0}")] ParseIpnet(#[from] ipnet::AddrParseError), #[error("parse ip: {0}")] ParseIp(#[from] net::AddrParseError), #[error("parse int: {0}")] ParseInt(#[from] ParseIntError), #[error("{0}")] Io(#[source] IoError), #[error("utf8: {0}")] Utf8(#[from] FromUtf8Error), #[error("{0}")] Std(#[source] StdError), #[error("{0}")] Other(String), } impl Error { pub fn from_std(error: T) -> Self where T: std::error::Error + Send + Sync + 'static, { Error::Std(StdError(Box::new(error))) } pub fn downcast_ref(&self) -> Option<&T> { if let Error::Std(s) = self { return s.0.downcast_ref(); } None } } #[derive(Debug, Error)] #[error("io error: {0}")] pub struct IoError(#[from] pub io::Error); // Workaround for wanting PartialEq for io::Error. impl PartialEq for IoError { fn eq(&self, other: &Self) -> bool { self.0.kind() == other.0.kind() } } impl From for Error { fn from(e: io::Error) -> Self { Error::Io(IoError(e)) } } /// An escape hatch to preserve stack traces when we don't know the error. /// /// This crate exports some traits such as `Conn` and `Listener`. The trait functions /// produce the local error `util::Error`. However when used in crates higher up the stack, /// we are forced to handle errors that are local to that crate. For example we use /// `Listener` the `dtls` crate and it needs to handle `dtls::Error`. /// /// By using `util::Error::from_std` we can preserve the underlying error (and stack trace!). #[derive(Debug, Error)] #[error("{0}")] pub struct StdError(pub Box); impl PartialEq for StdError { fn eq(&self, _: &Self) -> bool { false } }