core_extensions/
void.rs

1//! Contains types and functions for impossible situations.
2
3use std_::{cmp, fmt};
4
5/// Type for impossible situations.
6///
7/// Use this as a type parameter to enums to make the variants that use it unconstructible.
8///
9/// # Interaction with unsafe code
10///
11/// It is only valid to convert to Void from other Void-like types,
12/// it is undefined behavior to convert from any constructible type, even if zero-sized.
13///
14/// # Example, infinite loop which only returns on error.
15///
16#[cfg_attr(feature = "option_result", doc = " ```rust")]
17#[cfg_attr(not(feature = "option_result"), doc = " ```ignore")]
18/// use core_extensions::{ResultLikeExt, Void};
19///
20/// #[derive(Debug,PartialEq)]
21/// enum Error<T>{
22///     InvalidItem(T),
23///     IteratorWasntInfinite,
24/// }
25///
26/// fn reading_numbers<I>(i: I) -> Result<Void, Error<usize>>
27/// where I: IntoIterator<Item = usize>
28/// {
29///     for elem in i{
30///         if elem == 0 { return Err(Error::InvalidItem(elem)) }
31///         println!("{}", elem);
32///     }
33///     Err(Error::IteratorWasntInfinite)
34/// }
35///
36/// assert_eq!(reading_numbers(1..100).into_error(), Error::IteratorWasntInfinite);
37/// assert_eq!(reading_numbers(0..).into_error(), Error::InvalidItem(0));
38///
39///
40/// ```
41#[derive(Debug, Copy, Clone, Hash)]
42#[cfg_attr(feature = "docsrs", doc(cfg(feature = "void")))]
43pub enum Void {}
44
45impl Void {
46    /// Converts a `Void` to any type.
47    ///
48    /// Note that because `Void` is impossible to construct,
49    /// this method is unreachable.
50    pub fn to<T>(self) -> T {
51        match self {}
52    }
53}
54
55impl From<Void> for std_::convert::Infallible {
56    #[inline(always)]
57    fn from(this: Void) -> Self {
58        match this {}
59    }
60}
61
62/// There's also a `impl From<Void> for std_::convert::Infallible` impl
63/// that's not appearing in the docs for some reason.
64impl From<std_::convert::Infallible> for Void {
65    #[inline(always)]
66    fn from(this: std_::convert::Infallible) -> Self {
67        match this {}
68    }
69}
70
71#[cfg(std)]
72impl std_::error::Error for Void {
73    fn description(&self) -> &str {
74        match *self {}
75    }
76}
77
78impl fmt::Display for Void {
79    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
80        match *self {}
81    }
82}
83
84impl Eq for Void {}
85
86impl<T: ?Sized> PartialEq<T> for Void {
87    fn eq(&self, _: &T) -> bool {
88        self.to()
89    }
90}
91impl Ord for Void {
92    fn cmp(&self, _: &Self) -> cmp::Ordering {
93        self.to()
94    }
95}
96impl<T: ?Sized> PartialOrd<T> for Void {
97    fn partial_cmp(&self, _: &T) -> Option<cmp::Ordering> {
98        self.to()
99    }
100}
101
102#[cfg(feature = "serde_")]
103pub use self::serde_impl::DeserializeVoidError;
104#[cfg(feature = "serde_")]
105mod serde_impl {
106    use super::*;
107    use serde::de::Error;
108    use serde::{Deserialize, Deserializer, Serialize, Serializer};
109
110    /// Represents a deserialization error,when trying to deserialize a struct or enum variant
111    /// containing a `Void` field.
112    ///
113    /// Returned by serde::Deserialize::deserialize every time it's called.
114    #[derive(Debug, Copy, Clone)]
115    pub struct DeserializeVoidError;
116
117    impl fmt::Display for DeserializeVoidError {
118        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119            f.write_str(
120                "Cant deserialize a struct or \
121                 enum variant containing a core_extensions::Void.",
122            )
123        }
124    }
125
126    /// This impl is only enabled if the "serde_" feature is enabled.
127    ///
128    /// This always Returns an `Err(D::Error::custom(DeserializeVoidError))`.
129    impl<'de> Deserialize<'de> for Void {
130        fn deserialize<D>(_: D) -> Result<Self, D::Error>
131        where
132            D: Deserializer<'de>,
133        {
134            Err(D::Error::custom(DeserializeVoidError))
135        }
136    }
137
138    /// This impl is only enabled if the "serde_" feature is enabled.
139    ///
140    impl Serialize for Void {
141        fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
142        where
143            S: Serializer,
144        {
145            self.to()
146        }
147    }
148}