fieldwork-borrow 0.1.0

Field-level borrow splitting for Rust
Documentation
//! Field-level borrow splitting for Rust.
//!
//! Rust's borrow checker operates at the function boundary level, which sometimes
//! rejects code that is actually safe. This crate provides the [`with_!`] macro
//! that enables field-level borrow splitting, allowing you to work around these
//! "false positive" borrow checker errors.
//!
//! # The Problem
//!
//! Consider this common pattern that Rust rejects:
//!
//! ```compile_fail
//! struct Database { models: Vec<Model> }
//! struct Model { objects: Vec<Object> }
//! struct Object { matrix: f64 }
//!
//! struct Viewer {
//!     db: Database,
//!     model_id: usize,
//!     object_mats: Vec<f64>,
//! }
//!
//! impl Viewer {
//!     fn cur_model(&self) -> &Model {
//!         &self.db.models[self.model_id]
//!     }
//!
//!     fn problem(&mut self) {
//!         // ERROR: cannot borrow `self.object_mats` as mutable because
//!         // `self` is also borrowed as immutable (by cur_model)
//!         for obj in &self.cur_model().objects {
//!             self.object_mats.push(obj.matrix);
//!         }
//!     }
//! }
//! ```
//!
//! The code is safe because `cur_model()` only reads `db` and `model_id`,
//! while we're mutating `object_mats`. But Rust can't see through the method boundary.
//!
//! # The Solution
//!
//! ```
//! use fieldwork_borrow::with_;
//!
//! struct Database { models: Vec<Model> }
//! struct Model { objects: Vec<Object> }
//! struct Object { matrix: f64 }
//!
//! struct Viewer {
//!     db: Database,
//!     model_id: usize,
//!     object_mats: Vec<f64>,
//! }
//!
//! impl Viewer {
//!     fn problem(&mut self) {
//!         with_!(self, {
//!             methods {
//!                 cur_model(&db, copy model_id) -> &Model {
//!                     &db.models[model_id]
//!                 }
//!             }
//!             fields {
//!                 mut object_mats
//!             }
//!             body {
//!                 for obj in &self.cur_model().objects {
//!                     object_mats.push(obj.matrix);
//!                 }
//!             }
//!         });
//!     }
//! }
//! ```
//!
//! # Syntax
//!
//! ```text
//! with_!(receiver, {
//!     methods {
//!         method_name(field1, mut field2, copy field3, arg: Type) -> ReturnType {
//!             // method body
//!         }
//!     }
//!     fields {
//!         field_a           // immutable borrow
//!         mut field_b       // mutable borrow
//!     }
//!     body {
//!         // code that uses self.method_name() and self.field_x
//!     }
//! });
//! ```
//!
//! # Field Access Modes
//!
//! In method parameters:
//! - `field` or `&field` — shared reference (`&receiver.field`)
//! - `mut field` — mutable reference (`&mut receiver.field`)
//! - `copy field` — by value, requires `Copy` trait
//!
//! In `fields` block:
//! - `field` — shared reference
//! - `mut field` — mutable reference

pub use fieldwork_macro::with_;