1//! Traits for determining whether we can derive traits for a thing or not.
2//!
3//! These traits tend to come in pairs:
4//!
5//! 1. A "trivial" version, whose implementations aren't allowed to recursively
6//! look at other types or the results of fix point analyses.
7//!
8//! 2. A "normal" version, whose implementations simply query the results of a
9//! fix point analysis.
10//!
11//! The former is used by the analyses when creating the results queried by the
12//! second.
13
14use super::context::BindgenContext;
15
16use std::cmp;
17use std::ops;
18
19/// A trait that encapsulates the logic for whether or not we can derive `Debug`
20/// for a given thing.
21pub(crate) trait CanDeriveDebug {
22 /// Return `true` if `Debug` can be derived for this thing, `false`
23 /// otherwise.
24 fn can_derive_debug(&self, ctx: &BindgenContext) -> bool;
25}
26
27/// A trait that encapsulates the logic for whether or not we can derive `Copy`
28/// for a given thing.
29pub(crate) trait CanDeriveCopy {
30 /// Return `true` if `Copy` can be derived for this thing, `false`
31 /// otherwise.
32 fn can_derive_copy(&self, ctx: &BindgenContext) -> bool;
33}
34
35/// A trait that encapsulates the logic for whether or not we can derive
36/// `Default` for a given thing.
37pub(crate) trait CanDeriveDefault {
38 /// Return `true` if `Default` can be derived for this thing, `false`
39 /// otherwise.
40 fn can_derive_default(&self, ctx: &BindgenContext) -> bool;
41}
42
43/// A trait that encapsulates the logic for whether or not we can derive `Hash`
44/// for a given thing.
45pub(crate) trait CanDeriveHash {
46 /// Return `true` if `Hash` can be derived for this thing, `false`
47 /// otherwise.
48 fn can_derive_hash(&self, ctx: &BindgenContext) -> bool;
49}
50
51/// A trait that encapsulates the logic for whether or not we can derive
52/// `PartialEq` for a given thing.
53pub(crate) trait CanDerivePartialEq {
54 /// Return `true` if `PartialEq` can be derived for this thing, `false`
55 /// otherwise.
56 fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool;
57}
58
59/// A trait that encapsulates the logic for whether or not we can derive
60/// `PartialOrd` for a given thing.
61pub(crate) trait CanDerivePartialOrd {
62 /// Return `true` if `PartialOrd` can be derived for this thing, `false`
63 /// otherwise.
64 fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool;
65}
66
67/// A trait that encapsulates the logic for whether or not we can derive `Eq`
68/// for a given thing.
69pub(crate) trait CanDeriveEq {
70 /// Return `true` if `Eq` can be derived for this thing, `false` otherwise.
71 fn can_derive_eq(&self, ctx: &BindgenContext) -> bool;
72}
73
74/// A trait that encapsulates the logic for whether or not we can derive `Ord`
75/// for a given thing.
76pub(crate) trait CanDeriveOrd {
77 /// Return `true` if `Ord` can be derived for this thing, `false` otherwise.
78 fn can_derive_ord(&self, ctx: &BindgenContext) -> bool;
79}
80
81/// Whether it is possible or not to automatically derive trait for an item.
82///
83/// ```ignore
84/// No
85/// ^
86/// |
87/// Manually
88/// ^
89/// |
90/// Yes
91/// ```
92///
93/// Initially we assume that we can derive trait for all types and then
94/// update our understanding as we learn more about each type.
95#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
96pub enum CanDerive {
97 /// Yes, we can derive automatically.
98 Yes,
99
100 /// The only thing that stops us from automatically deriving is that
101 /// array with more than maximum number of elements is used.
102 ///
103 /// This means we probably can "manually" implement such trait.
104 Manually,
105
106 /// No, we cannot.
107 No,
108}
109
110impl Default for CanDerive {
111 fn default() -> CanDerive {
112 CanDerive::Yes
113 }
114}
115
116impl CanDerive {
117 /// Take the least upper bound of `self` and `rhs`.
118 pub(crate) fn join(self, rhs: Self) -> Self {
119 cmp::max(self, v2:rhs)
120 }
121}
122
123impl ops::BitOr for CanDerive {
124 type Output = Self;
125
126 fn bitor(self, rhs: Self) -> Self::Output {
127 self.join(rhs)
128 }
129}
130
131impl ops::BitOrAssign for CanDerive {
132 fn bitor_assign(&mut self, rhs: Self) {
133 *self = self.join(rhs)
134 }
135}
136