1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2024-12-02 11:03:18 +02:00

Split out example to separate page. (#319)

The example is quite long and so the page didn't easily fit on the
same screen as the explanation
This commit is contained in:
Andrew Walbran 2023-02-03 10:12:31 +00:00 committed by GitHub
parent 20f02db5f5
commit 1be641203e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 59 deletions

View File

@ -153,6 +153,7 @@
- [Structured Error Handling](error-handling/result.md)
- [Propagating Errors with ?](error-handling/try-operator.md)
- [Converting Error Types](error-handling/converting-error-types.md)
- [Example](error-handling/converting-error-types-example.md)
- [Deriving Error Enums](error-handling/deriving-error-enums.md)
- [Dynamic Error Types](error-handling/dynamic-errors.md)
- [Adding Context to Errors](error-handling/error-contexts.md)

View File

@ -0,0 +1,60 @@
# Converting Error Types
```rust,editable
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::fs::{self, File};
use std::io::{self, Read};
#[derive(Debug)]
enum ReadUsernameError {
IoError(io::Error),
EmptyUsername(String),
}
impl Error for ReadUsernameError {}
impl Display for ReadUsernameError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::IoError(e) => write!(f, "IO error: {}", e),
Self::EmptyUsername(filename) => write!(f, "Found no username in {}", filename),
}
}
}
impl From<io::Error> for ReadUsernameError {
fn from(err: io::Error) -> ReadUsernameError {
ReadUsernameError::IoError(err)
}
}
fn read_username(path: &str) -> Result<String, ReadUsernameError> {
let mut username = String::with_capacity(100);
File::open(path)?.read_to_string(&mut username)?;
if username.is_empty() {
return Err(ReadUsernameError::EmptyUsername(String::from(path)));
}
Ok(username)
}
fn main() {
//fs::write("config.dat", "").unwrap();
let username = read_username("config.dat");
println!("username or error: {username:?}");
}
```
<details>
Key points:
* The `username` variable can be either `Ok(string)` or `Err(error)`.
* Use the `fs::write` call to test out the different scenarios: no file, empty file, file with username.
It is good practice for all error types to implement `std::error::Error`, which requires `Debug` and
`Display`. It's generally helpful for them to implement `Clone` and `Eq` too where possible, to make
life easier for tests and consumers of your library. In this case we can't easily do so, because
`io::Error` doesn't implement them.
</details>

View File

@ -17,62 +17,3 @@ match expression {
The `From::from` call here means we attempt to convert the error type to the
type returned by the function:
```rust,editable
use std::error::Error;
use std::{fs, io};
use std::io::Read;
use std::fmt::{self, Display, Formatter};
#[derive(Debug)]
enum ReadUsernameError {
IoError(io::Error),
EmptyUsername(String),
}
impl Error for ReadUsernameError {}
impl Display for ReadUsernameError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::IoError(e) => write!(f, "IO error: {}", e),
Self::EmptyUsername(filename) => write!(f, "Found no username in {}", filename),
}
}
}
impl From<io::Error> for ReadUsernameError {
fn from(err: io::Error) -> ReadUsernameError {
ReadUsernameError::IoError(err)
}
}
fn read_username(path: &str) -> Result<String, ReadUsernameError> {
let mut username = String::with_capacity(100);
fs::File::open(path)?.read_to_string(&mut username)?;
if username.is_empty() {
return Err(ReadUsernameError::EmptyUsername(String::from(path)));
}
Ok(username)
}
fn main() {
//fs::write("config.dat", "").unwrap();
let username = read_username("config.dat");
println!("username or error: {username:?}");
}
```
<details>
Key points:
* The `username` variable can be either `Ok(string)` or `Err(error)`.
* Use the `fs::write` call to test out the different scenarios: no file, empty file, file with username.
It is good practice for all error types to implement `std::error::Error`, which requires `Debug` and
`Display`. It's generally helpful for them to implement `Clone` and `Eq` too where possible, to make
life easier for tests and consumers of your library. In this case we can't easily do so, because
`io::Error` doesn't implement them.
</details>