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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! mDNS module error definition.

use lib3h_protocol::discovery::error::DiscoveryError;
use regex;
use std::{error::Error as StdError, fmt, io, net};

pub type MulticastDnsResult<T> = Result<T, MulticastDnsError>;

/// An error that can occur when interacting with the algorithm.
// #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Debug)]
pub struct MulticastDnsError(Box<ErrorKind>);

impl MulticastDnsError {
    /// A constructor for `MulticastDnsError`.
    pub fn new(kind: ErrorKind) -> Self {
        MulticastDnsError(Box::new(kind))
    }

    /// Helper function to build a new error with an [Other](ErrorKind::Other) ErrorKind.
    pub fn new_other(s: &str) -> Self {
        MulticastDnsError::new(ErrorKind::Other(s.to_owned()))
    }

    /// Return the specific type of this error.
    pub fn kind(&self) -> &ErrorKind {
        &self.0
    }

    /// Unwrap this error into its underlying type.
    pub fn into_kind(self) -> ErrorKind {
        *self.0
    }
}

/// The specific type of an error.
#[derive(Debug)]
pub enum ErrorKind {
    /// An I/O error that occurred while processing a data stream.
    Io(io::Error),
    /// Error occuring from None Option
    NoneError(std::option::NoneError),
    /// Error occuring while parsing Adresses with the net module
    AddrParseError(net::AddrParseError),
    /// Error during probe.
    ProbeError,
    /// Error occuring while we try to get an available port from the host.
    NoAvailablePort,
    /// Error occuring while using Regex crate.
    RegexError(regex::Error),
    /// Error occuring while converting bytes to String.
    Utf8Error(std::str::Utf8Error),
    /// Error occuring while discovering participants on a network.
    DiscoveryError(DiscoveryError),
    /// Yet undefined error.
    Other(String),
    /// Hints that destructuring should not be exhaustive.
    ///
    /// This enum may grow additional variants, so this makes sure clients
    /// don't count on exhaustive matching. (Otherwise, adding a new variant
    /// could break existing code.)
    #[doc(hidden)]
    __Nonexhaustive,
}

impl StdError for MulticastDnsError {
    /// The lower-level source of this error, if any.
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        match *self.0 {
            ErrorKind::Io(ref err) => Some(err),
            ErrorKind::NoneError(ref _err) => None,
            ErrorKind::AddrParseError(ref err) => Some(err),
            ErrorKind::ProbeError => None,
            ErrorKind::NoAvailablePort => None,
            ErrorKind::Utf8Error(ref err) => Some(err),
            ErrorKind::DiscoveryError(ref err) => Some(err),
            ErrorKind::Other(ref _s) => None,
            _ => unreachable!(),
        }
    }
}

impl fmt::Display for MulticastDnsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self.0 {
            ErrorKind::Io(ref err) => err.fmt(f),
            ErrorKind::NoneError(ref _err) => write!(f, "None value encountered."),
            ErrorKind::AddrParseError(ref err) => err.fmt(f),
            ErrorKind::ProbeError => write!(f, "Error during probe."),
            ErrorKind::NoAvailablePort => write!(f, "No available port found on the host."),
            ErrorKind::Utf8Error(ref err) => err.fmt(f),
            ErrorKind::DiscoveryError(ref err) => err.fmt(f),
            ErrorKind::Other(ref s) => write!(f, "Unknown error encountered: '{}'.", s),
            _ => unreachable!(),
        }
    }
}

impl From<io::Error> for MulticastDnsError {
    fn from(err: io::Error) -> Self {
        MulticastDnsError::new(ErrorKind::Io(err))
    }
}

impl From<std::option::NoneError> for MulticastDnsError {
    fn from(err: std::option::NoneError) -> Self {
        MulticastDnsError::new(ErrorKind::NoneError(err))
    }
}

impl From<net::AddrParseError> for MulticastDnsError {
    fn from(err: net::AddrParseError) -> Self {
        MulticastDnsError::new(ErrorKind::AddrParseError(err))
    }
}

impl From<regex::Error> for MulticastDnsError {
    fn from(err: regex::Error) -> Self {
        MulticastDnsError::new(ErrorKind::RegexError(err))
    }
}

impl From<std::str::Utf8Error> for MulticastDnsError {
    fn from(err: std::str::Utf8Error) -> Self {
        MulticastDnsError::new(ErrorKind::Utf8Error(err))
    }
}

impl From<DiscoveryError> for MulticastDnsError {
    fn from(err: DiscoveryError) -> Self {
        MulticastDnsError::new(ErrorKind::DiscoveryError(err))
    }
}

impl From<MulticastDnsError> for DiscoveryError {
    fn from(err: MulticastDnsError) -> DiscoveryError {
        DiscoveryError::new_other(&format!("{}", err))
    }
}