Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mention delegation in docs
Browse files Browse the repository at this point in the history
tyranron committed Dec 18, 2023
1 parent 6f62ba5 commit 955ccbc
Showing 2 changed files with 90 additions and 5 deletions.
42 changes: 38 additions & 4 deletions impl/doc/debug.md
Original file line number Diff line number Diff line change
@@ -18,8 +18,6 @@ The variables available in the arguments is `self` and each member of the struct
structs being named with a leading underscore and their index, i.e. `_0`, `_1`, `_2`, etc.




### Generic data types

When deriving `Debug` for a generic struct/enum, all generic type arguments _used_ during formatting
@@ -53,8 +51,6 @@ The following where clauses would be generated:
- `&'a T1: Pointer`




### Custom trait bounds

Sometimes you may want to specify additional trait bounds on your generic type parameters, so that they could be used
@@ -88,6 +84,42 @@ trait MyTrait { fn my_function(&self) -> i32; }
```


### Delegation

If the top-level `#[debug("...", args...)]` attribute (the one for a whole struct or variant) is specified
and can be trivially substituted with a delegation call to the inner type, then all the additional
[formatting parameters][1] do work as expected:
```rust
# use derive_more::Debug;
#
#[derive(Debug)]
#[debug("{_0:o}")] // the same as calling `Octal::fmt()`
struct MyOctalInt(i32);

// so, additional formatting parameters do work transparently
assert_eq!(format!("{:03?}", MyInt(9)), "011");

#[derive(Debug)]
#[debug("{_0:02b}")] // cannot be trivially substituted with `Binary::fmt()`
struct MyBinaryInt(i32);

// so, additional formatting parameters have no effect
assert_eq!(format!("{:07?}", MyBinaryInt(2)), "10");
```

If, for some reason, delegation in trivial cases is not desired, it may be suppressed explicitly:
```rust
# use derive_more::Debug;
#
#[derive(Debug)]
#[debug("{}", format_args!("{_0:o}"))] // `format_args!()` opaques the inner type
struct MyOctalInt(i32);

// so, additional formatting parameters have no effect
assert_eq!(format!("{:07}", MyInt(9)), "11");
```




## Example usage
@@ -133,3 +165,5 @@ assert_eq!(format!("{:?}", E::EnumFormat(true)), "true");

[`format!()`]: https://doc.rust-lang.org/stable/std/macro.format.html
[`format_args!()`]: https://doc.rust-lang.org/stable/std/macro.format_args.html

[1]: https://doc.rust-lang.org/stable/std/fmt/index.html#formatting-parameters
53 changes: 52 additions & 1 deletion impl/doc/display.md
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ the supplied format, or an automatically inferred one.
You specify the format on each variant by writing e.g. `#[display("my val: {}", some_val * 2)]`.
For enums, you can either specify it on each variant, or on the enum as a whole.

For variants that don't have a format specified, it will simply defer to the format of the
For variants that don't have a format specified, it will simply delegate to the format of the
inner variable. If there is no such variable, or there is more than 1, an error is generated.


@@ -97,6 +97,52 @@ struct MyStruct<T, U, V> {
```


### Delegation

If the `#[display("...", args...)]` attribute is omitted, the implementation simply delegates to the format
of the inner type, so all the additional [formatting parameters][1] do work as expected:
```rust
# use derive_more::Display;
#
#[derive(Display)]
struct MyInt(i32);

assert_eq!(format!("{:03}", MyInt(7)), "007");
```

If the `#[display("...", args...)]` attribute is specified and can be trivially substituted with a delegation
call to the inner type, then delegation will work too:
```rust
# use derive_more::Display;
#
#[derive(Display)]
#[display("{_0:o}")] // the same as calling `Octal::fmt()`
struct MyOctalInt(i32);

// so, additional formatting parameters do work transparently
assert_eq!(format!("{:03}", MyInt(9)), "011");

#[derive(Display)]
#[display("{_0:02b}")] // cannot be trivially substituted with `Binary::fmt()`
struct MyBinaryInt(i32);

// so, additional formatting parameters have no effect
assert_eq!(format!("{:07}", MyBinaryInt(2)), "10");
```

If, for some reason, delegation in trivial cases is not desired, it may be suppressed explicitly:
```rust
# use derive_more::Display;
#
#[derive(Display)]
#[display("{}", format_args!("{_0:o}"))] // `format_args!()` opaques the inner type
struct MyOctalInt(i32);

// so, additional formatting parameters have no effect
assert_eq!(format!("{:07}", MyInt(9)), "11");
```




## Example usage
@@ -176,3 +222,8 @@ assert_eq!(UnitStruct {}.to_string(), "UnitStruct");
assert_eq!(PositiveOrNegative { x: 1 }.to_string(), "Positive");
assert_eq!(PositiveOrNegative { x: -1 }.to_string(), "Negative");
```




[1]: https://doc.rust-lang.org/stable/std/fmt/index.html#formatting-parameters

0 comments on commit 955ccbc

Please sign in to comment.