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