-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathusage.rs
78 lines (65 loc) · 1.81 KB
/
usage.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#![feature(try_blocks)]
use core::fmt;
use std::error::Error;
use std::fs::File;
use std::io;
use propagate::ErrorTrace;
#[derive(Debug)]
enum MyError {
Unlucky,
Io(io::Error),
TooSmall(u64),
}
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Unlucky => write!(f, "Not this time!"),
Self::Io(_) => write!(f, "I/O error"),
Self::TooSmall(size) => write!(f, "File too small: {} bytes", size),
}
}
}
impl Error for MyError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
MyError::Unlucky => None,
MyError::Io(e) => e.source(),
MyError::TooSmall(_) => None,
}
}
}
impl From<io::Error> for MyError {
fn from(e: io::Error) -> Self {
Self::Io(e)
}
}
fn file_size(path: &str) -> propagate::Result<u64, MyError> {
try {
// `?` coerces `std::result::Result<_, io::Error>` into
// `propagate::Result<_, MyError>`.
let size = File::open(path)?.metadata()?.len();
if size < 1024 {
// Option 1: Coerce a `std::result::Result` to a `propagate::Result`
// using `?`.
Err(MyError::TooSmall(size))?
}
size
}
}
fn maybe_file_size(path: &str) -> propagate::Result<u64, MyError> {
let lucky = (path.len() % 2) == 0;
try {
if !lucky {
// Option 2: Directly construct a `propagate::Result`
// using `ErrorTrace::new()`.
return propagate::Err(MyError::Unlucky, ErrorTrace::new());
}
file_size(path)?
}
}
fn main() -> propagate::Result<(), MyError> {
try {
let size = maybe_file_size("foo.txt")?;
println!("File size: {} KiB", size / 1024);
}
}