Skip to content

Commit a5b8886

Browse files
committed
Add try_fn to the crate docs + minor doc cleanups
1 parent 74947e7 commit a5b8886

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

src/lib.rs

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
#![no_std]
22

3-
//! Annotations a function that "throws" a Result.
3+
//! Annotates a function that "throws" a Result.
44
//!
5-
//! Inside functions tagged with `throws`, you can use `?` and the `throw!` macro to return errors,
6-
//! but you don't need to wrap the successful return values in `Ok`.
5+
//! Inside functions tagged with either `throws` or `try_fn`, you can use `?` and the `throw!`
6+
//! macro to return errors, but you don't need to wrap the successful return values in `Ok`.
77
//!
8-
//! Using this syntax, you can write fallible functions almost as if they were nonfallible. Every
8+
//! Using this syntax, you can write fallible functions almost as if they were infallible. Every
99
//! time a function call would return a `Result`, you "re-raise" the error using `?`, and if you
1010
//! wish to raise your own error, you can return it with the `throw!` macro.
1111
//!
12+
//! The difference between `throws` and `try_fn` is in the function signature, with `throws` you
13+
//! write the signature as if it were infallible too, it will be transformed into a `Result` for
14+
//! you. With `try_fn` you write the signature as normal and only the body of the function will be
15+
//! transformed.
16+
//!
1217
//! ## Example
18+
//!
1319
//! ```
1420
//! use std::io::{self, Read};
1521
//!
16-
//! use culpa::{throw, throws};
22+
//! use culpa::{throw, throws, try_fn};
1723
//!
1824
//! #[throws(io::Error)]
1925
//! fn check() {
@@ -27,13 +33,26 @@
2733
//!
2834
//! println!("Okay!");
2935
//! }
36+
//!
37+
//! #[try_fn]
38+
//! fn check_as_try_fn() -> std::io::Result<()> {
39+
//! let mut file = std::fs::File::open("The_House_of_the_Spirits.txt")?;
40+
//! let mut text = String::new();
41+
//! file.read_to_string(&mut text)?;
42+
//!
43+
//! if !text.starts_with("Barrabas came to us by sea, the child Clara wrote") {
44+
//! throw!(io::Error::from_raw_os_error(22));
45+
//! }
46+
//!
47+
//! println!("Okay!");
48+
//! }
3049
//! ```
3150
//!
32-
//! # Default Error Type
51+
//! # `throws` Default Error Type
3352
//!
34-
//! This macro supports a "default error type" - if you do not pass a type to the macro, it will
35-
//! use the type named `Error` in this scope. So if you have defined an error type in this
36-
//! module, that will be the error thrown by this function.
53+
//! The `throws` macro supports a "default error type" - if you do not pass a type to the macro, it
54+
//! will use the type named `Error` in the current scope. So if you have defined an error type in
55+
//! the module, that will be the error thrown by this function.
3756
//!
3857
//! You can access this feature by omitting the arguments entirely or by passing `_` as the type.
3958
//!
@@ -43,7 +62,7 @@
4362
//! use culpa::throws;
4463
//!
4564
//! // Set the default error type for this module:
46-
//! type Error = std::io::Error;
65+
//! use std::io::Error;
4766
//!
4867
//! #[throws]
4968
//! fn print() {
@@ -54,21 +73,28 @@
5473
//!
5574
//! # Throwing as an Option
5675
//!
57-
//! This syntax can also support functions which return an `Option` instead of a `Result`. The
58-
//! way to access this is to pass `as Option` as the argument to `throw`.
76+
//! This syntax can also support functions which return an `Option` instead of a `Result`. To use
77+
//! this with `throws` pass `as Option` as the argument in place of the error type, to use it with
78+
//! `try_fn` just put it as the return type like normal
5979
//!
6080
//! In functions that return `Option`, you can use the `throw!()` macro without any argument to
6181
//! return `None`.
6282
//!
6383
//! ## Example
6484
//!
6585
//! ```
66-
//! use culpa::{throw, throws};
67-
//!
68-
//! #[throws(as Option)]
86+
//! #[culpa::throws(as Option)]
6987
//! fn example<T: Eq + Ord>(slice: &[T], needle: &T) -> usize {
7088
//! if !slice.contains(needle) {
71-
//! throw!();
89+
//! culpa::throw!();
90+
//! }
91+
//! slice.binary_search(needle).ok()?
92+
//! }
93+
//!
94+
//! #[culpa::try_fn]
95+
//! fn example_as_try_fn<T: Eq + Ord>(slice: &[T], needle: &T) -> Option<usize> {
96+
//! if !slice.contains(needle) {
97+
//! culpa::throw!();
7298
//! }
7399
//! slice.binary_search(needle).ok()?
74100
//! }
@@ -78,15 +104,15 @@
78104
//!
79105
//! The `?` syntax in Rust is controlled by a trait called `Try`, which is currently unstable.
80106
//! Because this feature is unstable and I don't want to maintain compatibility if its interface
81-
//! changes, this crate currently only works with two stable `Try` types: Result and Option.
107+
//! changes, this crate currently only works with two stable `Try` types: `Result` and `Option`.
82108
//! However, its designed so that it will hopefully support other `Try` types as well in the
83109
//! future.
84110
//!
85111
//! It's worth noting that `Try` also has some other stable implementations: specifically `Poll`.
86112
//! Because of the somewhat unusual implementation of `Try` for those types, this crate does not
87113
//! support `throws` syntax on functions that return `Poll` (so you can't use this syntax when
88-
//! implementing a Future by hand, for example). I hope to come up with a way to support Poll in
89-
//! the future.
114+
//! implementing a `Future` by hand, for example). I hope to come up with a way to support `Poll`
115+
//! in the future.
90116
91117
#[doc(inline)]
92118
/// Annotates a function that "throws" a Result.

0 commit comments

Comments
 (0)