Skip to content

Commit 0d0ce84

Browse files
committed
added error example
1 parent add7ce9 commit 0d0ce84

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ in a controlled repository now.
1313
* `closures.rs`: closure examples
1414
* `lifetimes.rs`: simple lifetime example
1515
* `rc`: examples with `RefCell` and `Rc`
16+
* `error`: example of creating a custom error

error.rs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use std::io;
2+
use std::str::FromStr;
3+
4+
#[derive(Debug, PartialEq, Eq)]
5+
struct Point {
6+
x: i32,
7+
y: i32,
8+
}
9+
10+
#[derive(Debug)]
11+
enum PointError {
12+
CoordDescErr(std::num::ParseIntError),
13+
CoordCountErr(usize),
14+
}
15+
16+
impl std::fmt::Display for PointError {
17+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
18+
match *self {
19+
PointError::CoordDescErr(ref e) => write!(f, "coord parse error: {}", e),
20+
PointError::CoordCountErr(n) => write!(f, "expected 2 coords, got {}", n),
21+
}
22+
}
23+
}
24+
25+
impl std::error::Error for PointError {}
26+
27+
impl FromStr for Point {
28+
type Err = PointError;
29+
30+
fn from_str(s: &str) -> Result<Self, PointError> {
31+
let coords = s
32+
// XXX This will accept ((1,2)) etc.
33+
.trim_matches(|p| p == '(' || p == ')')
34+
.split(',')
35+
.map(|s| s.trim().parse().map_err(PointError::CoordDescErr))
36+
.collect::<Result<Vec<i32>, PointError>>()?;
37+
38+
if coords.len() != 2 {
39+
return Err(PointError::CoordCountErr(coords.len()));
40+
}
41+
42+
Ok(Point {
43+
x: coords[0],
44+
y: coords[1],
45+
})
46+
}
47+
}
48+
49+
fn main() -> Result<(), Box<dyn std::error::Error>> {
50+
let p = Point::from_str(
51+
&std::env::args()
52+
.nth(1)
53+
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "missing program argument"))?,
54+
)?;
55+
println!("{:?}", p);
56+
Ok(())
57+
}

0 commit comments

Comments
 (0)