1//! [`PartialOrd`](trait@std::cmp::PartialOrd) implementation.
2
3use proc_macro2::TokenStream;
4use quote::quote;
5
6use super::common_ord;
7use crate::{Data, DeriveTrait, Item, SimpleType, SplitGenerics, Trait, TraitImpl};
8
9/// Dummy-struct implement [`Trait`] for
10/// [`PartialOrd`](trait@std::cmp::PartialOrd).
11pub struct PartialOrd;
12
13impl TraitImpl for PartialOrd {
14 fn as_str(&self) -> &'static str {
15 "PartialOrd"
16 }
17
18 fn default_derive_trait(&self) -> DeriveTrait {
19 DeriveTrait::PartialOrd
20 }
21
22 fn build_signature(
23 &self,
24 any_bound: bool,
25 item: &Item,
26 generics: &SplitGenerics<'_>,
27 traits: &[DeriveTrait],
28 trait_: &DeriveTrait,
29 body: &TokenStream,
30 ) -> TokenStream {
31 let body = if !any_bound && traits.iter().any(|trait_| trait_ == Trait::Ord) {
32 quote! {
33 ::core::option::Option::Some(::core::cmp::Ord::cmp(self, __other))
34 }
35 } else {
36 common_ord::build_ord_signature(item, generics, traits, trait_, body)
37 };
38
39 quote! {
40 #[inline]
41 fn partial_cmp(&self, __other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
42 #body
43 }
44 }
45 }
46
47 fn build_body(
48 &self,
49 any_bound: bool,
50 traits: &[DeriveTrait],
51 trait_: &DeriveTrait,
52 data: &Data,
53 ) -> TokenStream {
54 if data.is_empty(**trait_)
55 || data.is_incomparable()
56 || (!any_bound && traits.iter().any(|trait_| trait_ == Trait::Ord))
57 {
58 TokenStream::new()
59 } else {
60 match data.simple_type() {
61 SimpleType::Struct(fields) | SimpleType::Tuple(fields) => {
62 let self_pattern = &fields.self_pattern;
63 let other_pattern = &fields.other_pattern;
64 let body = common_ord::build_ord_body(trait_, data);
65
66 quote! {
67 (#self_pattern, #other_pattern) => #body,
68 }
69 }
70 SimpleType::Unit(_) => TokenStream::new(),
71 SimpleType::Union(_) => unreachable!("unexpected trait for union"),
72 }
73 }
74 }
75}
76