Skip to content

Commit 7e5e434

Browse files
About impl Debug
I checked that the examples are compilable.
1 parent 5b18111 commit 7e5e434

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

CONTRIBUTING.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,70 @@ Additionally,
6767
An adaptor might use the inner iterator specializations for its own specializations.
6868

6969
## Additional implementations
70+
### The [`Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html) implementation
71+
All our iterators should implement `Debug`.
72+
73+
When one of the field is not debuggable (such as _functions_), you must not derive `Debug`.
74+
Instead, manually implement it and _ignore this field_ in our helper macro `debug_fmt_fields`.
75+
76+
<details>
77+
<summary>4 examples (click to expand)</summary>
78+
79+
```rust
80+
use std::fmt;
81+
82+
/* ===== Simple derive. ===== */
83+
#[derive(Debug)]
84+
struct Name1<I> {
85+
iter: I,
86+
}
87+
88+
/* ===== With an unclonable field. ===== */
89+
struct Name2<I, F> {
90+
iter: I,
91+
func: F,
92+
}
93+
94+
// No `F: Debug` bound and the field `func` is ignored.
95+
impl<I: fmt::Debug, F> fmt::Debug for Name2<I, F> {
96+
// it defines the `fmt` function from a struct name and the fields you want to debug.
97+
debug_fmt_fields!(Name2, iter);
98+
}
99+
100+
/* ===== With an unclonable field, but another bound to add. ===== */
101+
struct Name3<I: Iterator, F> {
102+
iter: I,
103+
item: Option<I::Item>,
104+
func: F,
105+
}
106+
107+
// Same about `F` and `func`, similar about `I` but we must add the `I::Item: Debug` bound.
108+
impl<I: Iterator + fmt::Debug, F> fmt::Debug for Name3<I, F>
109+
where
110+
I::Item: fmt::Debug,
111+
{
112+
debug_fmt_fields!(Name3, iter, item);
113+
}
114+
115+
/* ===== With an unclonable field for which we can provide some information. ===== */
116+
struct Name4<I, F> {
117+
iter: I,
118+
func: Option<F>,
119+
}
120+
121+
// If ignore a field is not good enough, implement Debug fully manually.
122+
impl<I: fmt::Debug, F> fmt::Debug for Name4<I, F> {
123+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124+
let func = if self.func.is_some() { "Some(_)" } else { "None" };
125+
f.debug_struct("Name4")
126+
.field("iter", &self.iter)
127+
.field("func", &func)
128+
.finish()
129+
}
130+
}
131+
```
132+
</details>
133+
70134
### When to implement [`std::iter::FusedIterator`](https://doc.rust-lang.org/std/iter/trait.FusedIterator.html)
71135
This trait should be implemented _by all iterators that always return `None` after returning `None` once_, because it allows to optimize `Iterator::fuse()`.
72136

0 commit comments

Comments
 (0)