impartial_ord/
lib.rs

1//! Derives a quicker `PartialOrd` for types that already implement `Ord`.
2//!
3//! [![Master CI badge](https://github.com/Alorel/impartial-ord-rs/actions/workflows/lint-n-test.yml/badge.svg?branch=master)](https://github.com/Alorel/impartial-ord-rs/actions/workflows/lint-n-test.yml?query=branch%3Amaster)
4//! [![crates.io badge](https://img.shields.io/crates/v/impartial-ord)](https://crates.io/crates/impartial-ord)
5//! [![docs.rs badge](https://img.shields.io/docsrs/impartial-ord?label=docs.rs)](https://docs.rs/impartial-ord)
6//! [![dependencies badge](https://img.shields.io/librariesio/release/cargo/impartial-ord)](https://libraries.io/cargo/impartial-ord)
7//!
8//! ```
9//! # use core::cmp::{PartialOrd, Ord, Ordering};
10//! # type Bar = u8;
11//! # type Baz = u8;
12//! #
13//! #[derive(impartial_ord::ImpartialOrd, Ord, PartialEq, Eq, Default, Debug)]
14//! struct MyStruct { foo: Bar, qux: Baz, }
15//!
16//! assert_eq!(MyStruct::default().partial_cmp(&MyStruct::default()), Some(Ordering::Equal));
17//! ```
18//!
19//! ### Generated output
20//!
21#![cfg_attr(doctest, doc = " ````no_test")]
22//! ```
23//! impl PartialOrd for MyStruct where Self: Ord {
24//!     #[inline]
25//!     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
26//!         Some(Ord::cmp(self, other))
27//!     }
28//! }
29//! ````
30//!
31
32use quote::quote;
33use syn::{parse_macro_input, parse_quote, DeriveInput};
34
35/// A quicker [PartialOrd](core::cmp::PartialOrd) for types that already implement
36/// [Ord](core::cmp::Ord). See [crate-level docs](crate).
37#[proc_macro_derive(ImpartialOrd)]
38pub fn derive_partial_ord(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
39    let DeriveInput {
40        ident,
41        mut generics,
42        ..
43    } = parse_macro_input!(input as DeriveInput);
44
45    let (gen_impl, gen_type, gen_where) = {
46        generics
47            .make_where_clause()
48            .predicates
49            .push(parse_quote! { Self: ::core::cmp::Ord });
50        generics.split_for_impl()
51    };
52
53    (quote! {
54        #[automatically_derived]
55        impl #gen_impl ::core::cmp::PartialOrd for #ident #gen_type #gen_where {
56            #[inline]
57            fn partial_cmp(&self, other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
58                ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
59            }
60        }
61    })
62    .into()
63}