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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//! Contains types and functions for impossible situations.

use std_::{cmp, fmt};

/// Type for impossible situations.
///
/// Use this as a type parameter to enums to make the variants that use it unconstructible.
///
/// This type is used in [ResultLike](../option_result_ext/trait.ResultLike.html)
/// to unwrap values that can only be either the ok or error variants of the type.
///
/// # Interaction with unsafe code
///
/// It is only valid to convert to Void from other Void-like types,
/// it is undefined behavior to convert from any constructible type,even if zero-sized.
///
/// # Example,infallible FromStr implementation.
///
/// ```
/// use std::str::FromStr;
/// use core_extensions::{SelfOps,ResultLike,Void};
///
/// #[derive(Debug,PartialEq)]
/// pub struct Double(pub String);
/// impl FromStr for Double{
///     type Err=Void;
///     fn from_str(s:&str)->Result<Self,Void>{
///         s.repeat(2)
///             .piped(Double)
///             .piped(Ok)
///     }
/// }
///
/// assert_eq!(
///     "12345".parse::<Double>().unwrap_safe(),
///     Double("12345".repeat(2))
/// );
///
/// ```
///
/// # Example,infinite loop which only returns on error.
///
/// ```
/// use core_extensions::{ResultLike,Void};
///
/// #[derive(Debug,PartialEq)]
/// enum Error<T>{
///     InvalidItem(T),
///     IteratorWasntInfinite,
/// }
/// fn reading_numbers<I>(i:I)->Result<Void,Error<usize>>
/// where I:IntoIterator<Item=usize>
/// {
///     for elem in i{
///         if elem==0 { return Err(Error::InvalidItem(elem)) }
///         println!("{}",elem);
///     }
///     Err(Error::IteratorWasntInfinite)
/// }
///
/// assert_eq!(reading_numbers(1..100).unwrap_err_safe() , Error::IteratorWasntInfinite);
/// assert_eq!(reading_numbers(0..).unwrap_err_safe() , Error::InvalidItem(0));
///
///
/// ```
#[derive(Debug, Copy, Clone, Hash)]
pub enum Void {}

impl Void {
    /// Converts a `Void` to any type.
    ///
    /// Note that because `Void` is impossible to construct,
    /// this method is unreachable.
    pub fn to<T>(self) -> T {
        match self {}
    }
}

// Conflicts with the built-in `impl Into<T> for T{...}`
// impl<T> Into<T> for Void{
//     fn into(_:Self)->T{
//         self.to()
//     }
// }

#[cfg(std)]
impl std_::error::Error for Void {
    fn description(&self) -> &str {
        match *self {}
    }
}

impl fmt::Display for Void {
    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
        match *self {}
    }
}

impl Eq for Void {}

impl<T: ?Sized> PartialEq<T> for Void {
    fn eq(&self, _: &T) -> bool {
        self.to()
    }
}
impl Ord for Void {
    fn cmp(&self, _: &Self) -> cmp::Ordering {
        self.to()
    }
}
impl<T: ?Sized> PartialOrd<T> for Void {
    fn partial_cmp(&self, _: &T) -> Option<cmp::Ordering> {
        self.to()
    }
}

#[cfg(feature = "serde_")]
pub use self::serde_impl::DeserializeVoidError;
#[cfg(feature = "serde_")]
mod serde_impl {
    use super::*;
    use serde::de::Error;
    use serde::{Deserialize, Deserializer, Serialize, Serializer};

    /// Represents a deserialization error,when trying to deserialize a struct or enum variant
    /// containing a `Void` field.
    ///
    /// Returned by serde::Deserialize::deserialize every time it's called.
    #[derive(Debug, Copy, Clone)]
    pub struct DeserializeVoidError;

    impl fmt::Display for DeserializeVoidError {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.write_str(
                "Cant deserialize a struct or \
                 enum variant containing a core_extensions::Void.",
            )
        }
    }

    /// This impl is only enabled if the "serde_" feature is enabled.
    ///
    /// This always Returns an `Err(D::Error::custom(DeserializeVoidError))`.
    impl<'de> Deserialize<'de> for Void {
        fn deserialize<D>(_: D) -> Result<Self, D::Error>
        where
            D: Deserializer<'de>,
        {
            Err(D::Error::custom(DeserializeVoidError))
        }
    }

    /// This impl is only enabled if the "serde_" feature is enabled.
    ///
    impl Serialize for Void {
        fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            self.to()
        }
    }
}