thiserror
The thiserror crate provides macros to help avoid boilerplate when defining error types. It provides derive macros that assist in implementing From<T>, Display, and the Error trait.
1. ```
use std::io::Read;
```
2. ```
use std::{fs, io};
```
3. ```
use thiserror::Error;
```
5. ```
#[derive(Debug, Error)]
```
6. ```
enum ReadUsernameError {
```
7. ```
#[error("I/O error: {0}")]
```
8. ```
IoError(#[from] io::Error),
```
9. ```
#[error("Found no username in {0}")]
```
10. ```
EmptyUsername(String),
```
11. ```
}
```
13. ```
fn read_username(path: &str) -> Result<String, ReadUsernameError> {
```
14. ```
let mut username = String::with_capacity(100);
```
15. ```
fs::File::open(path)?.read_to_string(&mut username)?;
```
16. ```
if username.is_empty() {
```
17. ```
return Err(ReadUsernameError::EmptyUsername(String::from(path)));
```
18. ```
}
```
19. ```
Ok(username)
```
20. ```
}
```
22. ```
fn main() {
```
23. ```
//fs::write("config.dat", "").unwrap();
```
24. ```
match read_username("config.dat") {
```
25. ```
Ok(username) => println!("Username: {username}"),
```
26. ```
Err(err) => println!("Error: {err:?}"),
```
27. ```
}
```
28. ```
}
```
This slide should take about 5 minutes.
- The
Errorderive macro is provided bythiserror, and has lots of useful attributes to help define error types in a compact way. - The message from
#[error]is used to derive theDisplaytrait. - Note that the (
thiserror::)Errorderive macro, while it has the effect of implementing the (std::error::)Errortrait, is not the same this; traits and macros do not share a namespace.
