# declarative_lock

A thread-aware, deadlock-free resource locking manager for Rust.

## Overview

`declarative_lock` enforces **declaration-before-locking** for resources, guaranteeing deadlock freedom in concurrent environments. By requiring threads to explicitly declare which resources they intend to lock before acquiring any locks, this crate prevents deadlocks caused by lock acquisition order across threads and detects double-locking of the same resource within a single thread.

## Features

- **Deadlock-Free by Design**  
  - Threads must declare all resources they will lock before locking begins.
  - The system blocks conflicting declarations, ensuring that no two threads can declare overlapping resources simultaneously.
  - This mechanism eliminates deadlocks caused by cyclic lock dependencies between threads.
  - Double-locking of the same resource in the same thread is detected and prevented.

- **Separation of Resource Identity and Instance**  
  - The crate separates the resource's identifier (used for declaration and locking) from its actual instance.
  - Multiple resource instances can share the same identifier, allowing flexible management.
  - For example, if different types (with distinct functionality and internal types) depend on the same underlying resource, you can assign them the same identifier.  
    This enables independent management of each resource while ensuring mutual exclusion for the shared underlying resource.

## Example

```rust
use declarative_locker::{DeclarativeLock, DeclarativeLocker};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum ResourceType {
    Database,
    SomeOtherResource,
}

let lock = DeclarativeLock::<ResourceType>::new();

// Create two lockers for different resources sharing the same identifier
let db_locker = DeclarativeLocker::new(&lock, ResourceType::Database, db_instance);
let cache_locker = DeclarativeLocker::new(&lock, ResourceType::Database, cache_instance);

// Declare intent to lock Database
let guard = lock.declare(&[ResourceType::Database]).unwrap();

// Both lockers will enforce mutual exclusion on the underlying Database resource
let db_guard = db_locker.lock().unwrap();
// ... use db_guard ...
drop(db_guard);

drop(guard); // Declaration is automatically cleaned up
```

## Safety

- All declarations and locks are tracked per-thread.
- Resources cannot be locked unless declared.
- Double-locking and conflicting declarations are prevented at runtime.

## Changelog

- v0.1.0 (2025/11/27)

    Initial Version

## License

MIT
