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}