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
//! ```
//! # use core::cmp::{PartialOrd, Ord, Ordering};
//! # type Bar = u8;
//! # type Baz = u8;
//! #
//! // Input
//! #[derive(PartialEq, Eq, Ord, impartial_ord::ImpartialOrd)]
//! # struct Impostor;
//! # #[derive(PartialEq, Eq, Ord)]
//! struct MyStruct { foo: Bar, qux: Baz, }
//!
//! // Output
//! impl PartialOrd for MyStruct where Self: Ord {
//! #[inline]
//! fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
//! Some(Ord::cmp(self, other))
//! }
//! }
//! ```
use quote::quote;
use syn::{parse2, parse_macro_input, DeriveInput, WherePredicate};
/// A quicker [PartialOrd](core::cmp::PartialOrd) for types that already implement
/// [Ord](core::cmp::Ord).
#[proc_macro_derive(ImpartialOrd)]
pub fn derive_partial_ord(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let DeriveInput {
ident,
mut generics,
..
} = parse_macro_input!(input as DeriveInput);
let (gen_impl, gen_type, gen_where) = {
let self_predicate = match parse2::<WherePredicate>(quote! { Self: ::core::cmp::Ord }) {
Ok(p) => p,
Err(e) => return e.to_compile_error().into(),
};
generics.make_where_clause().predicates.push(self_predicate);
generics.split_for_impl()
};
(quote! {
#[automatically_derived]
impl #gen_impl ::core::cmp::PartialOrd for #ident #gen_type #gen_where {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
Some(::core::cmp::Ord::cmp(self, other))
}
}
})
.into()
}