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
//! 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.
///
/// # 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, infinite loop which only returns on error.
///
#[cfg_attr(feature = "option_result", doc = " ```rust")]
#[cfg_attr(not(feature = "option_result"), doc = " ```ignore")]
/// use core_extensions::{ResultLikeExt, 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).into_error(), Error::IteratorWasntInfinite);
/// assert_eq!(reading_numbers(0..).into_error(), Error::InvalidItem(0));
///
///
/// ```
#[derive(Debug, Copy, Clone, Hash)]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "void")))]
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 {}
    }
}

impl From<Void> for std_::convert::Infallible {
    #[inline(always)]
    fn from(this: Void) -> Self {
        match this {}
    }
}

/// There's also a `impl From<Void> for std_::convert::Infallible` impl
/// that's not appearing in the docs for some reason.
impl From<std_::convert::Infallible> for Void {
    #[inline(always)]
    fn from(this: std_::convert::Infallible) -> Self {
        match this {}
    }
}

#[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()
        }
    }
}