impartial_ord/lib.rs
1//! Derives a quicker `PartialOrd` for types that already implement `Ord`.
2//!
3//! [](https://github.com/Alorel/impartial-ord-rs/actions/workflows/lint-n-test.yml?query=branch%3Amaster)
4//! [](https://crates.io/crates/impartial-ord)
5//! [](https://docs.rs/impartial-ord)
6//! [](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}