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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! # trait_guard
//!
//! `trait_guard` is a macro used to protect a trait implementation from usage with a custom message, note, and label.
//!
//! It abuses the `on_unimplemented` attribute to provide a custom error message when the trait is not implemented. It requires
//! the `negative_impls` and `trivial_bounds` nightly features to be enabled.
//!
//! You can use any trait (even if it's an STD trait or from another crate)!
//!
//! ## Example usage:
//!
//! ```rust
//! trait_guard!(
//! MyType, // the type that will be guarded
//! MyTrait, // the trait that is being guarded
//!
//! trait_guard = MyGuardTrait, // optional: custom name for the guard trait, shown in the diagnostic message
//! guard_struct = MyGuardStruct, // optional: custom name for the guard struct, shown in the diagnostic message
//!
//! {
//! // this is the body of the trait implementation
//! fn my_method(&self) {
//! // implementation
//! }
//! },
//!
//! message = "MyType does not implement MyTrait",
//! // note = "This is a custom note",
//! // label = "MyType needs to implement MyTrait"
//! );
//! ```
//!
//! The example above will refuse to compile if the `MyTrait` implementation of `MyType` is used anywhere in the user's code.
//!
//! If you want to guard multiple traits/types, you can change the name of `trait_guard` and `guard_struct` to avoid conflicts.
//!
//! ## Example for [`std::fmt::Display`]
//!
//! ```rust
//! use trait_guard::trait_guard;
//!
//! #[derive(Debug)]
//! struct A;
//!
//! trait_guard!(
//! A, // the type that will be guarded
//! std::fmt::Display, // the trait that is being guarded
//!
//! {
//! // this is the body of the trait implementation
//! fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
//! unreachable!("It will never be called because A does not implement Display");
//! }
//! },
//!
//! message = "A does not implement std::fmt::Display",
//! );
//! ```
/// A macro to protect a trait implementation from usage with a custom message, note, and label.
///
/// This abuses the `on_unimplemented` attribute to provide a custom error message when the trait is not implemented. It requires
/// the `negative_impls` and `trivial_bounds` nightly features to be enabled.
///
/// You can use any trait (even if it's an STD trait or from another crate)!
///
/// # Example usage:
///
/// ```rust
/// trait_guard!(
/// MyType, // the type that will be guarded
/// MyTrait, // the trait that is being guarded
///
/// trait_guard = MyGuardTrait, // optional: custom name for the guard trait, shown in the diagnostic message
/// guard_struct = MyGuardStruct, // optional: custom name for the guard struct, shown in the diagnostic message
///
/// {
/// // this is the body of the trait implementation
/// fn my_method(&self) {
/// // implementation
/// }
/// },
///
/// message = "MyType does not implement MyTrait",
/// // note = "This is a custom note",
/// // label = "MyType needs to implement MyTrait"
/// );
/// ```
///
/// The example above will refuse to compile if the `MyTrait` implementation of `MyType` is used anywhere in the user's code.
///
/// If you want to guard multiple traits/types, you can change the name of `trait_guard` and `guard_struct` to avoid conflicts.