Skip to content

Commit

Permalink
Merge pull request #10 from alecmocatta/v0.1.5
Browse files Browse the repository at this point in the history
V0.1.5
  • Loading branch information
alecmocatta authored Oct 17, 2019
2 parents bd3eb85 + 901960d commit 840b826
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 15 deletions.
10 changes: 4 additions & 6 deletions .mergify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ pull_request_rules:
conditions:
- base=master
- status-success=tests
- label!=work-in-progress
- "label!=work in progress"
- "#approved-reviews-by>=1"
- "#review-requested=0"
- "#changes-requested-reviews-by=0"
- "#commented-reviews-by=0"
actions:
merge:
method: merge
Expand All @@ -17,11 +16,10 @@ pull_request_rules:
conditions:
- base=master
- status-success=tests
- label!=work-in-progress
- "label!=work in progress"
- author=alecmocatta # https://github.com/Mergifyio/mergify-engine/issues/451
- "#review-requested=0"
- "#changes-requested-reviews-by=0"
- "#commented-reviews-by=0"
actions:
merge:
method: merge
Expand All @@ -36,10 +34,10 @@ pull_request_rules:
- "title~=^WIP: .*"
actions:
label:
add: ["work-in-progress"]
add: ["work in progress"]
- name: auto remove wip label
conditions:
- "-title~=^WIP: .*"
actions:
label:
remove: ["work-in-progress"]
remove: ["work in progress"]
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "replace_with"
version = "0.1.4"
version = "0.1.5"
license = "MIT OR Apache-2.0"
authors = ["Alec Mocatta <[email protected]>"]
categories = ["rust-patterns"]
Expand All @@ -10,7 +10,7 @@ Temporarily take ownership of a value at a mutable location, and replace it with
"""
repository = "https://github.com/alecmocatta/replace_with"
homepage = "https://github.com/alecmocatta/replace_with"
documentation = "https://docs.rs/replace_with/0.1.4"
documentation = "https://docs.rs/replace_with/0.1.5"
readme = "README.md"
edition = "2018"

Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
[![MIT / Apache 2.0 licensed](https://img.shields.io/crates/l/replace_with.svg?maxAge=2592000)](#License)
[![Build Status](https://dev.azure.com/alecmocatta/replace_with/_apis/build/status/tests?branchName=master)](https://dev.azure.com/alecmocatta/replace_with/_build/latest?branchName=master)

[Docs](https://docs.rs/replace_with/0.1.4)
[Docs](https://docs.rs/replace_with/0.1.5)

Temporarily take ownership of a value at a mutable location, and replace it with a new value based on the old one.

This crate provides the function [`replace_with()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with.html), which is like [`std::mem::replace()`](https://doc.rust-lang.org/std/mem/fn.replace.html) except it allows the replacement value to be mapped from the original value.
This crate provides the function [`replace_with()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with.html), which is like [`std::mem::replace()`](https://doc.rust-lang.org/std/mem/fn.replace.html) except it allows the replacement value to be mapped from the original value.

See [RFC 1736](https://github.com/rust-lang/rfcs/pull/1736) for a lot of discussion as to its merits. It was never merged, and the desired ability to temporarily move out of `&mut T` doesn't exist yet, so this crate is my interim solution.

It's very akin to [`take_mut`](https://github.com/Sgeo/take_mut), though uses `Drop` instead of [`std::panic::catch_unwind()`](https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) to react to unwinding, which avoids the optimisation barrier of calling the `extern "C" __rust_maybe_catch_panic()`. As such it's up to ∞x faster. The API also attempts to make slightly more explicit the behavior on panic – [`replace_with()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with.html) accepts two closures such that aborting in the "standard case" where the mapping closure (`FnOnce(T) -> T`) panics (as [`take_mut::take()`](https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html) does) is avoided. If the second closure (`FnOnce() -> T`) panics, however, then it does indeed abort. The "abort on first panic" behaviour is available with [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_abort.html).
It's very akin to [`take_mut`](https://github.com/Sgeo/take_mut), though uses `Drop` instead of [`std::panic::catch_unwind()`](https://doc.rust-lang.org/std/panic/fn.catch_unwind.html) to react to unwinding, which avoids the optimisation barrier of calling the `extern "C" __rust_maybe_catch_panic()`. As such it's up to ∞x faster. The API also attempts to make slightly more explicit the behavior on panic – [`replace_with()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with.html) accepts two closures such that aborting in the "standard case" where the mapping closure (`FnOnce(T) -> T`) panics (as [`take_mut::take()`](https://docs.rs/take_mut/0.2.2/take_mut/fn.take.html) does) is avoided. If the second closure (`FnOnce() -> T`) panics, however, then it does indeed abort. The "abort on first panic" behaviour is available with [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with_or_abort.html).

## Example

Expand Down Expand Up @@ -70,9 +70,9 @@ features = []
...
```

The [`replace_with()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with.html) & [`replace_with_or_default()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_default.html) functions are available on stable Rust both, with and without `std`.
The [`replace_with()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with.html) & [`replace_with_or_default()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with_or_default.html) functions are available on stable Rust both, with and without `std`.

The [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_abort.html) function however by default makes use of [`std::process::abort()`](https://doc.rust-lang.org/std/process/fn.abort.html) which is not available with `no_std`.
The [`replace_with_or_abort()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with_or_abort.html) function however by default makes use of [`std::process::abort()`](https://doc.rust-lang.org/std/process/fn.abort.html) which is not available with `no_std`.

As such `replace_with` will by default call [`core::intrinsics::abort()`](https://doc.rust-lang.org/core/intrinsics/fn.abort.html) instead, which in turn requires nightly Rust.

Expand Down Expand Up @@ -102,7 +102,7 @@ features = ["panic_abort"]
...
```

… the `"panic_abort"` feature enables the [`replace_with_or_abort_unchecked()`](https://docs.rs/replace_with/0.1.4/replace_with/fn.replace_with_or_abort_unchecked.html) function becomes on stable Rust as an `unsafe` function, a simple wrapper around `ptr::write(dest, f(ptr::read(dest)));`.
… the `"panic_abort"` feature enables the [`replace_with_or_abort_unchecked()`](https://docs.rs/replace_with/0.1.5/replace_with/fn.replace_with_or_abort_unchecked.html) function becomes on stable Rust as an `unsafe` function, a simple wrapper around `ptr::write(dest, f(ptr::read(dest)));`.

**Word of caution:** It is crucial to only ever use this function having defined `panic = "abort"`, or else bad things may happen. It's *up to you* to uphold this invariant!

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
all(not(feature = "std"), feature = "nightly"),
feature(core_intrinsics)
)]
#![doc(html_root_url = "https://docs.rs/replace_with/0.1.4")]
#![doc(html_root_url = "https://docs.rs/replace_with/0.1.5")]
#![warn(
missing_copy_implementations,
missing_debug_implementations,
Expand Down

0 comments on commit 840b826

Please sign in to comment.