replace_with

Temporarily take ownership of a value behind a mutable reference and replace it with a value mapped from the old one.

Library
Cargo
v0.1.8
125stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity0
Maintenance20
Community44
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture80
Code Quality82
Innovation74
Learning Curve88

replace_with is a tiny Rust utility crate that solves a common ownership problem: mapping a value in place behind a &mut T when you need to move out of the old value to compute the new one. Its replace_with() function is like std::mem::replace(), except the replacement is produced by a closure that consumes the original value, which is exactly what Rust’s borrow checker normally forbids.

It is closely related to take_mut but uses Drop rather than std::panic::catch_unwind to handle unwinding, avoiding an optimization barrier and running significantly faster. The crate offers explicit control over panic behavior via a fallback closure or the abort-on-panic variant, and it supports no_std environments.

What You Get

  • replace_with(place, default_closure, map_closure) for in-place mapping with a panic fallback
  • replace_with_or_abort() for the simpler abort-on-panic behavior
  • A faster alternative to take_mut that avoids catch_unwind’s optimization barrier
  • Well-defined panic semantics: the mapping closure can panic without aborting when a fallback is given
  • no_std support and an optional nightly feature for core::intrinsics::abort()

Common Use Cases

  • Transitioning an enum state machine in place behind &mut self
  • Replacing a value with one computed by consuming the old value
  • Avoiding cannot move out of borrowed content errors without unsafe
  • Working in no_std contexts where take_mut is unavailable or heavier

Under The Hood

Architecture - The crate is a single small module exposing a few free functions. replace_with reads the value out of the &mut T with ptr::read, hands ownership to the mapping closure, and ptr::writes the returned value back. To stay sound if the closure unwinds, it installs a Drop guard that runs a supplied fallback (or aborts) so the referenced location is never left uninitialized. This differs from take_mut, which relies on catch_unwind; using Drop avoids the extern “C” __rust_maybe_catch_panic optimization barrier.

Tech Stack - 100% Rust, no runtime dependencies. It is no_std-capable behind a default std feature, with an optional nightly feature that swaps the abort path to core::intrinsics::abort(). Distributed as the replace_with Cargo crate and documented on docs.rs.

Code Quality - Despite being tiny (~21 KB of Rust), the crate is careful about the subtle unsafe/unwind-safety it encapsulates, exposing a fully safe public API. It is mature and battle-tested (19M+ downloads) though largely in maintenance mode with low recent activity.

API Design - The API is minimal and purpose-built: replace_with(place, default, map) for full control over panic behavior and replace_with_or_abort(place, map) for the common case. The motivating enum-state-machine example in the README makes the intended usage immediately clear, keeping the learning curve very low.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search