nevermore/lib.rs
1//! Conveniences for the bottom type [`core::convert::Infallible`].
2//!
3//! This may become redundant if (hopefully *once*)
4//! never type is fully [stabilized][never-type-tracking-issue].
5//!
6//! [never-type-tracking-issue]: https://github.com/rust-lang/rust/issues/35121
7
8use proc_macro::TokenStream;
9use quote::quote;
10use syn::{parse_macro_input, DeriveInput};
11
12/// Implements conversion [from][`From`] [`core::convert::Infallible`] for the struct.
13///
14/// The common use-case is to use it on custom error types in APIs
15/// so that a generic interface can return the result of an arbitrary associated type
16/// but be easily convertible into a more specific type.
17///
18/// # Examples
19///
20/// Basic usage:
21///
22/// ```
23/// use nevermore::FromNever;
24///
25/// fn assert_from_never<T: From<core::convert::Infallible>>() {}
26///
27/// #[derive(FromNever)]
28/// pub struct User {
29/// username: String,
30/// age: u8,
31/// }
32///
33/// assert_from_never::<User>();
34/// ```
35///
36/// Error type polymorphism:
37///
38/// ```
39/// use std::convert::Infallible;
40/// use std::io::{self, Read};
41/// use nevermore::FromNever;
42///
43/// /// A type which may be decoded from source input.
44/// trait Decode {
45/// type Error;
46///
47/// /// Decodes the packet.
48/// fn decode(read: impl Read) -> Result<Self, Self::Error>
49/// where Self: Sized;
50/// }
51///
52/// /// Foo packet.
53/// pub struct Foo(i32);
54///
55/// impl Decode for Foo {
56/// type Error = FooDecodeError;
57///
58/// fn decode(mut read: impl Read) -> Result<Self, Self::Error> {
59/// let mut buffer = [0; 4];
60/// read.read_exact(&mut buffer)?;
61///
62/// Ok(Self(i32::from_be_bytes(buffer)))
63/// }
64/// }
65///
66/// /// Bar packet. This is empty thus its deserialization cannot fail
67/// /// since it does no require any bytes to be read.
68/// pub struct Bar;
69///
70/// impl Decode for Bar {
71/// // Although the trait permits us to fail, we always succeed.
72/// type Error = Infallible;
73///
74/// fn decode(read: impl Read) -> Result<Self, Self::Error> {
75/// Ok(Self)
76/// }
77/// }
78///
79/// #[derive(thiserror::Error, Debug)]
80/// pub enum FooDecodeError {
81/// #[error("an I/O error has occurred {0}")]
82/// Io(#[from] io::Error),
83/// }
84///
85/// /// An error which may appear while decoding either `Foo` or `Bar` packet.
86/// #[derive(thiserror::Error, FromNever, Debug)]
87/// pub enum PacketDecodeError {
88/// #[error("failed to deserialize Foo packet")]
89/// Foo(#[from] <Foo as Decode>::Error),
90/// // there is no need for a separate uninhabited type now since
91/// // we've made this type implement `From<Error>`
92/// }
93///
94/// fn decode_foo_bar(mut buffer: impl Read) -> Result<(Foo, Bar), PacketDecodeError> {
95/// // we use `?` with both calls to `decode`:
96/// Ok((
97/// // will use thiserror-generated `From<FooDecodeError>`
98/// Foo::decode(&mut buffer)?,
99/// // will use `From<Infallible>`
100/// Bar::decode(&mut buffer)?,
101/// ))
102/// }
103///
104/// let mut buffer = vec![0x12u8, 0x34u8, 0x56u8, 0x78u8];
105/// # let _ =
106/// decode_foo_bar(&*buffer.as_mut_slice());
107/// ```
108#[proc_macro_derive(FromNever)]
109pub fn derive_from_never(input: TokenStream) -> TokenStream {
110 let DeriveInput {
111 ident, generics, ..
112 } = parse_macro_input!(input as DeriveInput);
113
114 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
115
116 proc_macro::TokenStream::from(quote!(
117 impl #impl_generics ::core::convert::From<::core::convert::Infallible>
118 for #ident #ty_generics #where_clause {
119 fn from(infallible: ::core::convert::Infallible) -> Self {
120 match infallible {}
121 }
122 }
123 ))
124}