summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md89
-rw-r--r--src/lib.rs132
2 files changed, 208 insertions, 13 deletions
diff --git a/README.md b/README.md
index d53a4d6..57027c5 100644
--- a/README.md
+++ b/README.md
@@ -5,17 +5,17 @@ don't want our programs to panic because of that. We also don't want to spend
so much time handling unexpected errors. That's what this crate is for. You
keep your unexpected errors, and don't worry about them until later.
-* This crate works in `no-std`, although most features (besides [`Exun`]) require
+* This crate works in `no-std`, although most features (besides `Exun`) require
`alloc`.
-* [`Exun`] is an error type. It'll hold on to your [`Unexpected`] error if you have
+* `Exun` is an error type. It'll hold on to your `Unexpected` error if you have
one, so you can figure out what to do with it later. If the error is
-[`Expected`], then it'll hold onto that too.
+`Expected`, then it'll hold onto that too.
-* [`RawUnexpected`] bottles up all of your unexpected errors. There's also
-[`UnexpectedError`], which implements [`Error`].
+* `RawUnexpected` bottles up all of your unexpected errors. There's also
+`UnexpectedError`, which implements `Error`.
-* [`Expect`] is a type alias for [`Exun<E, RawUnexpected>`].
+* `Expect` is a type alias for `Exun<E, RawUnexpected>`.
* Clearly mark errors that you don't expect to occur by calling
`Result::unexpect`. If the error type doesn't implement `Error`, you can still
@@ -24,7 +24,7 @@ use `Result::unexpect_msg`, as long as it implements
## Usage
-The only pre-requisite is Rust 1.54.
+The only pre-requisite is Rust 1.41.1.
For standard features:
@@ -37,12 +37,12 @@ exun = "0.1"
The following features are enabled by default:
* `std`: This automatically enables `alloc`. It's used for the standard
-library's [`Error`] type. Using this type allows more errors to be converted
-into [`Exun`] and [`RawUnexpected`] errors automatically, and it's needed for
+library's `Error` type. Using this type allows more errors to be converted
+into `Exun` and `RawUnexpected` errors automatically, and it's needed for
`Result::unexpect`.
-* `alloc`: This is needed for [`Expect`], [`RawUnexpected`] and
-[`UnexpectedError`], as well as `Result::unexpected_msg`.
+* `alloc`: This is needed for `Expect`, `RawUnexpected` and
+`UnexpectedError`, as well as `Result::unexpected_msg`.
To disable these features:
@@ -62,4 +62,69 @@ exun = { version = "0.1", default-features = false, features = ["alloc"] }
## Examples
-[`Error`]: https://doc.rust-lang.org/stable/std/fmt/struct.Error.html
+```rust
+use exun::*;
+
+fn foo(num: &str) -> Result<i32, RawUnexpected> {
+ // we use `unexpect` to indicate that we don't expect this error to occur
+ let num = num.parse::<i32>().unexpect()?;
+ Ok(num)
+}
+```
+
+```rust
+use std::error::Error;
+use std::fmt::{self, Display};
+
+use exun::*;
+
+#[derive(Debug)]
+struct NoNumberError;
+
+impl Display for NoNumberError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "no number provided")
+ }
+}
+
+impl Error for NoNumberError {}
+
+fn foo(num: Option<&str>) -> Result<i32, Expect<NoNumberError>> {
+ let num = num.ok_or(NoNumberError)?; // we expect that this may return an error
+ let num = num.parse::<i32>().unexpect()?; // but we think the number is otherwise parsable
+ Ok(num)
+}
+```
+
+```rust
+use std::error::Error;
+use std::fmt::{self, Display};
+use std::num::ParseIntError;
+
+use exun::*;
+
+#[derive(Debug)]
+struct NoNumberError;
+
+impl Display for NoNumberError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "no number provided")
+ }
+}
+
+impl Error for NoNumberError {}
+
+fn foo(num: Option<&str>) -> Result<i32, Exun<&str, ParseIntError>> {
+ // we expect it possible to not get a number, so we handle it as such
+ let num = match num {
+ Some(num) => num,
+ None => return Err(Expected("no number provided")),
+ };
+
+ // however, we expect that the number is otherwise parsable
+ match num.parse() {
+ Ok(int) => Ok(int),
+ Err(e) => Err(Unexpected(e))
+ }
+}
+```
diff --git a/src/lib.rs b/src/lib.rs
index d47c604..7383557 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,7 +2,137 @@
#![warn(clippy::nursery)]
#![warn(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)]
-#![doc = include_str!("../README.md")]
+//! There are many errors we don't expect to occur. But what if we're wrong? We
+//! don't want our programs to panic because of that. We also don't want to spend
+//! so much time handling unexpected errors. That's what this crate is for. You
+//! keep your unexpected errors, and don't worry about them until later.
+//!
+//! * This crate works in `no-std`, although most features (besides [`Exun`]) require
+//! `alloc`.
+//!
+//! * [`Exun`] is an error type. It'll hold on to your [`Unexpected`] error if you have
+//! one, so you can figure out what to do with it later. If the error is
+//! [`Expected`], then it'll hold onto that too.
+//!
+//! * [`RawUnexpected`] bottles up all of your unexpected errors. There's also
+//! [`UnexpectedError`], which implements [`Error`].
+//!
+//! * [`Expect`] is a type alias for [`Exun<E, RawUnexpected>`].
+//!
+//! * Clearly mark errors that you don't expect to occur by calling
+//! `Result::unexpect`. If the error type doesn't implement `Error`, you can still
+//! use `Result::unexpect_msg`, as long as it implements
+//! `Debug + Display + Send + Sync + 'static`.
+//!
+//! ## Usage
+//!
+//! The only pre-requisite is Rust 1.41.1.
+//!
+//! For standard features:
+//!
+//! ```toml
+//! [dependencies]
+//! # ...
+//! exun = "0.1"
+//! ```
+//!
+//! The following features are enabled by default:
+//!
+//! * `std`: This automatically enables `alloc`. It's used for the standard
+//! library's [`Error`] type. Using this type allows more errors to be converted
+//! into [`Exun`] and [`RawUnexpected`] errors automatically, and it's needed for
+//! `Result::unexpect`.
+//!
+//! * `alloc`: This is needed for [`Expect`], [`RawUnexpected`] and
+//! [`UnexpectedError`], as well as `Result::unexpected_msg`.
+//!
+//! To disable these features:
+//!
+//! ```toml
+//! [dependencies]
+//! # ...
+//! exun = { version = "0.1", default-features = false }
+//! ```
+//!
+//! If you'd like to use `alloc` but not `std`:
+//!
+//! ```toml
+//! [dependencies]
+//! # ...
+//! exun = { version = "0.1", default-features = false, features = ["alloc"] }
+//! ```
+//!
+//! ## Examples
+//!
+//! ```
+//! use exun::*;
+//!
+//! fn foo(num: &str) -> Result<i32, RawUnexpected> {
+//! // we use `unexpect` to indicate that we don't expect this error to occur
+//! let num = num.parse::<i32>().unexpect()?;
+//! Ok(num)
+//! }
+//! ```
+//!
+//! ```
+//! use std::error::Error;
+//! use std::fmt::{self, Display};
+//!
+//! use exun::*;
+//!
+//! #[derive(Debug)]
+//! struct NoNumberError;
+//!
+//! impl Display for NoNumberError {
+//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+//! write!(f, "no number provided")
+//! }
+//! }
+//!
+//! impl Error for NoNumberError {}
+//!
+//! fn foo(num: Option<&str>) -> Result<i32, Expect<NoNumberError>> {
+//! let num = num.ok_or(NoNumberError)?; // we expect that this may return an error
+//! let num = num.parse::<i32>().unexpect()?; // but we think the number is otherwise parsable
+//! Ok(num)
+//! }
+//! ```
+//!
+//! ```
+//! use std::error::Error;
+//! use std::fmt::{self, Display};
+//! use std::num::ParseIntError;
+//!
+//! use exun::*;
+//!
+//! #[derive(Debug)]
+//! struct NoNumberError;
+//!
+//! impl Display for NoNumberError {
+//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+//! write!(f, "no number provided")
+//! }
+//! }
+//!
+//! impl Error for NoNumberError {}
+//!
+//! fn foo(num: Option<&str>) -> Result<i32, Exun<&str, ParseIntError>> {
+//! // we expect it possible to not get a number, so we handle it as such
+//! let num = match num {
+//! Some(num) => num,
+//! None => return Err(Expected("no number provided")),
+//! };
+//!
+//! // however, we expect that the number is otherwise parsable
+//! match num.parse() {
+//! Ok(int) => Ok(int),
+//! Err(e) => Err(Unexpected(e))
+//! }
+//! }
+//! ```
+//!
+//! [`Error`]: `std::error::Error
+//!
#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc;