Skip to content

Commit 05c6fc4

Browse files
authored
Improve Display / Debug description (cairo-book#722)
1 parent d729e1e commit 05c6fc4

6 files changed

Lines changed: 43 additions & 15 deletions

File tree

.trunk/trunk.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ runtimes:
1919
lint:
2020
enabled:
2121
- actionlint@1.6.27
22-
- checkov@3.2.50
22+
- checkov@3.2.55
2323
- clippy@1.65.0
2424
- git-diff-check
2525
- markdownlint@0.39.0

listings/ch11-advanced-features/no_listing_06_format_macro/src/lib.cairo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ fn main() {
1111
let s = format!("{s1}-{s2}-{s3}"); // s1, s2, s3 are not consumed by format!
1212
// or
1313
let s = format!("{}-{}-{}", s1, s2, s3);
14+
1415
println!("{}", s);
1516
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use core::fmt::Formatter;
2+
23
fn main() {
34
let mut formatter: Formatter = Default::default();
45
let a = 10;
56
let b = 20;
67
write!(formatter, "hello");
78
write!(formatter, "world");
89
write!(formatter, " {a} {b}");
10+
911
println!("{}", formatter.buffer); // helloworld 10 20
1012
}

listings/ch11-advanced-features/no_listing_10_display_trait_with_write/src/lib.cairo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ impl PointDisplay of Display<Point> {
1010
fn fmt(self: @Point, ref f: Formatter) -> Result<(), Error> {
1111
let x = *self.x;
1212
let y = *self.y;
13-
return writeln!(f, "Point ({x}, {y})");
13+
14+
writeln!(f, "Point ({x}, {y})")
1415
}
1516
}
1617

src/appendix-03-derivable-traits.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ Example:
3232
{{#include ../listings/appendix/listing_02_copy/src/lib.cairo}}
3333
```
3434

35-
## `Debug` for Programmer Output
35+
## `Debug` for Printing and Debugging
3636

3737
The `Debug` trait enables debug formatting in format strings, which you indicate by adding `:?` within `{}` placeholders.
3838

39-
The `Debug` trait allows you to print instances of a type for debugging purposes, so you and other programmers using your type can inspect an instance at a particular point in a program’s execution.
39+
It allows you to print instances of a type for debugging purposes, so you and other programmers using this type can inspect an instance at a particular point in a program’s execution.
4040

41-
For example:
41+
For example, if you want to print the value of a variable of type `Point`, you can do it as follows:
4242

4343
```rust
4444
{{#include ../listings/appendix/listing_03_debug/src/lib.cairo}}
@@ -49,7 +49,7 @@ scarb cairo-run
4949
Point { x: 1, y: 3 }
5050
```
5151
52-
The `Debug` trait is required, for example, in use of the `assert_eq!` macro in tests. This macro prints the values of instances given as arguments if the equality assertion fails so programmers can see why the two instances weren’t equal.
52+
The `Debug` trait is required, for example, when using the `assert_xx!` macros in tests. Theses macros print the values of instances given as arguments if the equality or comparison assertion fails so programmers can see why the two instances weren’t equal.
5353
5454
## `PartialEq` for Equality Comparisons
5555

src/ch11-09-printing.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
When writing a program, it is quite common to print some data to the console, either for the normal process of the program or for debugging purpose. In this chapter, we describe the options you have to print simple and complex data types.
44

5-
## Printing standard data types
5+
## Printing Standard Data Types
66

77
Cairo provides two macros to print standard data types:
88

@@ -22,6 +22,8 @@ Here are some examples:
2222
{{#include ../listings/ch11-advanced-features/no_listing_08_print_macro/src/lib.cairo}}
2323
```
2424

25+
> `print!` and `println!` macros use the `Display` trait under the hood, and are therefore used to print the value of types that implement it. This is the case for basic data types, but not for more complexe ones. If you try to print complex data types values with these macros, e.g., for debugging purpose, you will get an error. In that case, you can either [manually implement](./ch11-09-printing.md#printing-custom-data-types) the `Display` trait for your type, or use the `Debug` trait (see [below](./ch11-09-printing.md#print-debug-traces)).
26+
2527
## Formatting
2628

2729
Cairo also provides a useful macro to handle strings formatting: `format!`. This macro works like `println!`, but instead of printing the output to the screen, it returns a `ByteArray` with the contents. In the following example, we perform string concatenation using either the `+` operator or the
@@ -31,19 +33,33 @@ Cairo also provides a useful macro to handle strings formatting: `format!`. This
3133
{{#include ../listings/ch11-advanced-features/no_listing_06_format_macro/src/lib.cairo}}
3234
```
3335

34-
## Printing custom data types
36+
## Printing Custom Data Types
37+
38+
As previously explained, if you try to print the value of a custom data type with `print!` or `println!` macros, you'll get an error telling you that the `Display` trait is not implemented for your custom type:
39+
40+
```shell
41+
error: Trait has no implementation in context: core::fmt::Display::<package_name::struct_name>
42+
```
3543

36-
If you try to print a custom data type with `print!` and `println!` macros, you'll get an error telling you that the `Display` trait is not implemented for your custom type.
44+
The `println!` macro can do many kinds of formatting, and by default, the curly brackets tell `println!` to use formatting known as `Display`: output intended for direct end user consumption. The primitive types we’ve seen so far implement `Display` by default because there’s only one way you’d want to show a `1` or any other primitive type to a user. But with structs, the way `println!` should format the output is less clear because there are more display possibilities: Do you want commas or not? Do you want to print the curly brackets? Should all the fields be shown? Due to this ambiguity, Cairo doesn’t try to guess what we want, and structs don’t have a provided implementation of `Display` to use with `println!` and the `{}` placeholder.
3745

3846
Here is the `Display` trait to implement:
3947

40-
```rust
48+
```rust,noplayground
4149
trait Display<T> {
4250
fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>;
4351
}
4452
```
4553

46-
The second parameter `f` is a `Formatter`, which is just a struct containing a `ByteArray`, representing the pending result of formatting.
54+
The second parameter `f` is a `Formatter`, which is just a struct containing a `ByteArray`, representing the pending result of formatting:
55+
56+
```rust,noplayground
57+
#[derive(Default, Drop)]
58+
pub struct Formatter {
59+
/// The pending result of formatting.
60+
pub buffer: ByteArray,
61+
}
62+
```
4763

4864
Knowing this, here is an example of how to implement the `Display` trait for a custom `Point` struct:
4965

@@ -52,18 +68,26 @@ Knowing this, here is an example of how to implement the `Display` trait for a c
5268
```
5369

5470
Cairo also provides the `write!` and `writeln!` macros to write formatted strings in a formatter.
55-
Here are some examples:
71+
Here is a short example using `write!` macro to concatenate multiple strings on the same line and then print the result:
5672

5773
```rust
5874
{{#include ../listings/ch11-advanced-features/no_listing_07_write_macro/src/lib.cairo}}
5975
```
6076

61-
So, you can also implement the `Display` trait for the `Point` struct as follows:
77+
It is also possible to implement the `Display` trait for the `Point` struct using these macros, as shown here:
6278

6379
```rust
6480
{{#include ../listings/ch11-advanced-features/no_listing_10_display_trait_with_write/src/lib.cairo}}
6581
```
6682

67-
## Print debug traces
83+
> Printing complex data types this way might not be ideal as it requires additional steps to allow the use of `print!` and `println!` macros. If you need to print complexe data types, especially when debugging, use the `Debug` trait described just after instead.
84+
85+
## Print Debug Traces
86+
87+
Cairo provides the derivable trait `Debug` to print the value of variables when debugging. Simply add `:?` within curly brackets `{}` placeholders in a `print!` or `println!` macro string input.
88+
89+
This trait is very useful and is implemented by default for basic data types. It can also be simply derived on complex data types using the `derive(Debug)` attribute, as long as all types they contain implement it. It allows to get rid of manually implementing extra-code to print complex data types values.
90+
91+
Note that `assert_xx!` macros used in tests require the provided values to implement the `Debug` trait, as they also print the result in case of assertion failure.
6892

69-
To print some debug data, Cairo provides the derivable trait `Debug`. Look at the [Derivable Traits](appendix-03-derivable-traits.md) appendix, for more details.
93+
Please refer to the [Derivable Traits](appendix-03-derivable-traits.md#debug-trait-for-printing-and-debugging) appendix for more detail about the `Debug` trait and its usage for printing value when debugging.

0 commit comments

Comments
 (0)