You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-06-17 22:57:35 +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:
@ -153,6 +153,7 @@
|
|||||||
- [Structured Error Handling](error-handling/result.md)
|
- [Structured Error Handling](error-handling/result.md)
|
||||||
- [Propagating Errors with ?](error-handling/try-operator.md)
|
- [Propagating Errors with ?](error-handling/try-operator.md)
|
||||||
- [Converting Error Types](error-handling/converting-error-types.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)
|
- [Deriving Error Enums](error-handling/deriving-error-enums.md)
|
||||||
- [Dynamic Error Types](error-handling/dynamic-errors.md)
|
- [Dynamic Error Types](error-handling/dynamic-errors.md)
|
||||||
- [Adding Context to Errors](error-handling/error-contexts.md)
|
- [Adding Context to Errors](error-handling/error-contexts.md)
|
||||||
|
60
src/error-handling/converting-error-types-example.md
Normal file
60
src/error-handling/converting-error-types-example.md
Normal 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>
|
@ -17,62 +17,3 @@ match expression {
|
|||||||
|
|
||||||
The `From::from` call here means we attempt to convert the error type to the
|
The `From::from` call here means we attempt to convert the error type to the
|
||||||
type returned by the function:
|
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>
|
|
||||||
|
Reference in New Issue
Block a user