handle_trait 1.1.0

A trait for types that represent handles to shared resources
Documentation
# handle_trait

A Rust crate providing the `Handle` trait for types that represent handles to shared resources.

## Overview

The `Handle` trait identifies types that function as handles to underlying resources. A handle's defining feature is that cloning it results in a second value that accesses the same underlying resource, creating what can be thought of as "entanglement", where modifications visible through one handle appear in all other handles to the same resource.

This trait is based on the concept described in [Niko Matsakis's blog post about the Handle trait](https://smallcultfollowing.com/babysteps/blog/2025/10/07/the-handle-trait/).

## Why Use Handle?

The `handle()` method is semantically equivalent to `clone()`, but makes the code's intent much clearer. When you see `.handle()`, you immediately know that:

1. You're creating another reference to the same underlying resource
2. Changes through one handle will be visible through all handles
3. No deep copying or independent duplication is occurring

Compare:
```rust
let tx2 = tx.clone();  // Are we copying the channel? Creating a new one?
let tx2 = tx.handle(); // Clearly creating another handle to the same channel
```

## Usage

Add this to your `Cargo.toml`:

```toml
[dependencies]
handle_trait = "1"
```

### Using the Derive Macro

You can automatically implement `Handle` for your types using the derive macro:

```rust
use handle_trait::Handle;
use std::sync::Arc;

#[derive(Clone, Handle)]
struct MyHandle {
    inner: Arc<i32>,
}

let h1 = MyHandle { inner: Arc::new(42) };
let h2 = h1.handle(); // Creates another handle to the same resource
```

The derive macro works with generic types and where clauses:

```rust
use handle_trait::Handle;
use std::sync::Arc;

#[derive(Clone, Handle)]
struct GenericHandle<T> {
    inner: Arc<T>,
}
```

To disable the derive feature (if you only need the trait):

```toml
[dependencies]
handle_trait = { version = "1", default-features = false }
```

## Trait Definition

```rust
trait Handle: Clone {
    fn handle(&self) -> Self {
        self.clone()
    }
}
```

That's it.

This is only for semantics, it doesn't do anything differently than Clone.

In fact here is 100% of the actual code, verbatim, for this entire crate:

```rust
pub trait Handle: Clone {
    #[inline]
    #[must_use = "creating a handle without using it has no effect"]
    fn handle(&self) -> Self {
        self.clone()
    }
}

use std::rc::Rc;
use std::sync::{Arc, mpsc};

impl<T: ?Sized> Handle for &T {}
impl<T: ?Sized> Handle for Rc<T> {}
impl<T: ?Sized> Handle for Arc<T> {}
impl<T> Handle for mpsc::Sender<T> {}
impl<T> Handle for mpsc::SyncSender<T> {}
```
## Implementations

This crate provides `Handle` implementations for:

- **Shared references**: `&T`
- **Reference-counted pointers**: `Rc<T>` and `Arc<T>`
- **Channel endpoints**: `mpsc::Sender<T>` and `mpsc::SyncSender<T>`

Note that `Box<T>` does **not** implement `Handle` because cloning a `Box` creates an independent copy, not a handle to the same resource.

## Design Philosophy

The `Handle` trait exposes the semantic concept of sharing rather than operational details. This makes it clearer when types should implement it and encourages developers to use `handle()` instead of `clone()` for improved code clarity.

When a type implements `Handle`, it communicates to users that:
- Cloning creates entanglement, not independence
- The type manages shared access to an underlying resource
- Multiple handles coordinate access to the same data

## License

This project is licensed under the MIT License.

## Acknowledgments

This crate is based on the `Handle` trait concept proposed by Niko Matsakis in his blog post ["The Handle Trait"](https://smallcultfollowing.com/babysteps/blog/2025/10/07/the-handle-trait/).