setup_read_cleanup 0.6.0

A library for safely transitioning through the three phases of shared resource access: setup, read, and cleanup.
Documentation
# [setup_read_cleanup][repo-url] [![crates.io][cratesio-img]][cratesio-url] [![doc.rs][docrs-img]][docrs-url] [![CI Status][ci-img]][ci-url] [![MIT License][mit-img]][mit-url]

A library for managing data through distinct lifecycle phases: `Setup` -> `Read` -> `Cleanup`.

This crate provides "phased cells", a collection of smart pointer types that enforce a specific lifecycle for the data they manage. This is useful for data that is initialized once, read by multiple threads or tasks for a period, and then explicitly destroyed.

## Core Concepts

The lifecycle is divided into three phases:

-   **`Setup`**: The initial phase. The data can be mutably accessed for initialization.
-   **`Read`**: The operational phase. The data can only be accessed immutably. This phase is optimized for concurrent, lock-free reads.
-   **`Cleanup`**: The final phase. The data can be mutably accessed again for deconstruction or resource cleanup.

### Panic Handling in Transition Closures

The `transition_to_read` and `transition_to_cleanup` methods execute user-provided closures. If a panic occurs within these closures, `PhasedCell` ensures the following behavior across all its variants:

-   **`transition_to_read`**: If the closure panics, the cell's phase is safely reverted to `Setup`.
-   **`transition_to_cleanup`**: If the closure panics, the cell's phase is safely transitioned to `Cleanup`.

In both cases, any acquired internal mutexes are released before the panic is resumed, preventing deadlocks. The original panic is re-propagated, maintaining Rust's panic-safety guarantees while ensuring internal consistency.


## Cell Variants

This crate offers several cell variants to suit different concurrency needs:

-   [`PhasedCell`]https://docs.rs/setup_read_cleanup/latest/setup_read_cleanup/struct.PhasedCell.html: The basic cell. It is `Sync`, allowing it to be shared across threads for reading. However, mutable access via `get_mut_unlocked` is not thread-safe and requires the caller to ensure exclusive access.
-   [`PhasedCellSync`]https://docs.rs/setup_read_cleanup/latest/setup_read_cleanup/struct.PhasedCellSync.html: A thread-safe version that uses a `std::sync::Mutex` to allow for safe concurrent mutable access during the `Setup` and `Cleanup` phases.
-   [`PhasedCellAsync`]https://docs.rs/setup_read_cleanup/latest/setup_read_cleanup/struct.PhasedCellAsync.html: (Requires the `tokio` feature) An `async` version of `PhasedCellSync` that uses a `tokio::sync::Mutex`.

## Graceful Features

(Requires the `graceful` feature)

The `graceful` module provides wrappers that add graceful capabilities to phased cells:

-   **Graceful Cleanup**: It ensures that all ongoing read operations complete before allowing
    the cell to fully transition to the `Cleanup` phase.
-   **Graceful Read**: If a read operation is attempted while the cell is in the
    `Setup` phase and transitioning to `Read`, the read operation
    will wait for the transition to complete and for the cell to enter the `Read` phase.

It provides the following cells:


-   [`GracefulPhasedCell`]https://docs.rs/setup_read_cleanup/latest/setup_read_cleanup/graceful/struct.GracefulPhasedCell.html
-   [`GracefulPhasedCellSync`]https://docs.rs/setup_read_cleanup/latest/setup_read_cleanup/graceful/struct.GracefulPhasedCellSync.html
-   [`GracefulPhasedCellAsync`]https://docs.rs/setup_read_cleanup/latest/setup_read_cleanup/graceful/struct.GracefulPhasedCellAsync.html (Requires `graceful` and `tokio` features)

## Features

-   `tokio`: Enables the `async` cell variants (`PhasedCellAsync`, `GracefulPhasedCellAsync`) which use `tokio::sync`.
-   `graceful`: Enables the `graceful` module, which provides cells with graceful cleanup capabilities.

## Examples

Using a `static PhasedCellSync` to initialize data, read it from multiple threads, and then clean it up.

```rust
use setup_read_cleanup::{PhasedCellSync, Phase};
use std::thread;

struct MyData {
    items: Vec<i32>,
}

// Declare a static PhasedCellSync instance
static CELL: PhasedCellSync<MyData> = PhasedCellSync::new(MyData { items: Vec::new() });

fn main() {
    // --- Setup Phase ---
    assert_eq!(CELL.phase(), Phase::Setup);
    {
        let mut data = CELL.lock().unwrap();
        data.items.push(10);
        data.items.push(20);
    } // Lock is released here

    // --- Transition to Read Phase ---
    CELL.transition_to_read(|data| {
        data.items.push(30);
        Ok::<(), std::io::Error>(())
    }).unwrap();
    assert_eq!(CELL.phase(), Phase::Read);

    // --- Read Phase ---
    // Now, multiple threads can read the data concurrently.
    let mut handles = Vec::new();
    for i in 0..3 {
        handles.push(thread::spawn(move || {
            let data = CELL.read().unwrap(); // Access the static CELL
            println!("Thread {} reads: {:?}", i, data.items);
            assert_eq!(data.items, &[10, 20, 30]);
        }));
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // --- Transition to Cleanup Phase ---
    CELL.transition_to_cleanup(|data| {
        println!("Cleaning up. Final item: {:?}", data.items.pop());
        Ok::<(), std::io::Error>(())
    }).unwrap();
    assert_eq!(CELL.phase(), Phase::Cleanup);

    println!("Example finished successfully!");
}
``````

## Installation

In Cargo.toml, write this crate as a dependency:

```toml
[dependencies]
setup_read_cleanup = "0.6.0"
```

## Supported Rust versions

This crate supports Rust 1.74.1 or later.

```sh
% ./build.sh msrv
  [Meta]   cargo-msrv 0.18.4

Compatibility Check #1: Rust 1.74.1
  [OK]     Is compatible

Compatibility Check #2: Rust 1.65.0
  [FAIL]   Is incompatible

Compatibility Check #3: Rust 1.69.0
  [FAIL]   Is incompatible

Compatibility Check #4: Rust 1.71.1
  [FAIL]   Is incompatible

Compatibility Check #5: Rust 1.72.1
  [FAIL]   Is incompatible

Compatibility Check #6: Rust 1.73.0
  [FAIL]   Is incompatible

Result:
   Considered (min … max):   Rust 1.56.1 … Rust 1.91.1
   Search method:            bisect
   MSRV:                     1.74.1
   Target:                   x86_64-apple-darwin
```

## License

Copyright (C) 2025 Takayuki Sato

This program is free software under MIT License.<br>
See the file LICENSE in this distribution for more details.


[repo-url]: https://github.com/sttk/setup_read_cleanup-rust
[cratesio-img]: https://img.shields.io/badge/crates.io-ver.0.6.0-fc8d62?logo=rust
[cratesio-url]: https://crates.io/crates/setup_read_cleanup
[docrs-img]: https://img.shields.io/badge/doc.rs-setup_read_cleanup-66c2a5?logo=docs.rs
[docrs-url]: https://docs.rs/setup_read_cleanup
[ci-img]: https://github.com/sttk/setup_read_cleanup-rust/actions/workflows/rust.yml/badge.svg?branch=main
[ci-url]: https://github.com/sttk/setup_read_cleanup-rust/actions?query=branch%3Amain
[mit-img]: https://img.shields.io/badge/license-MIT-green.svg
[mit-url]: https://opensource.org/licenses/MIT