typed_use_cases 0.1.2

Formalize use cases at the type level. Zero runtime overhead. Experimental proof-of-concept.
Documentation
# typed_use_cases

**Formalize use cases at the type level. Zero runtime overhead.**

A Rust library that brings UML use cases into your type system, providing compile-time awareness when your code structure changes in ways that affect declared use cases.

> ⚠️ **Experimental**: This is a proof-of-concept library. It has not been validated in production environments and should be considered an exploratory tool for representing use cases in type systems.

---

## The Problem

In traditional development, use cases live outside the code:

- **Maintained manually**: Use case diagrams and specifications are separate documents
- **Silent drift**: When code changes, no one remembers to update the use cases
- **Becomes stale**: Documentation diverges from implementation over time
- **Poorly defined**: Use cases often end up ambiguous, generic, or unmeasurable
- **Abandoned**: Teams stop using use cases because they're too hard to maintain

The fundamental issue: **use cases and code evolve independently with no connection between them**.

---

## What This Library Does

`typed_use_cases` brings use cases into your type system with **zero runtime cost**:

- **Formalizes use cases** as named traits in Rust
- **Compile-time awareness**: The compiler knows which use cases exist
- **Breaking changes are visible**: If you change a method signature or remove an implementation, the compiler breaks at the use case level
- **No runtime overhead**: Uses a zero-sized System type (0 bytes)
- **Verification in tests only**: Uses `#[cfg(test)]` to verify implementations

### What This Library Is NOT

This library is **not**:

- **NOT a verification tool** - It does not prove your program satisfies a use case
-**NOT a testing framework** - It does not test that your system fulfills use case requirements (this is not feasible to automate)
-**NOT a formal methods tool** - It does not prove program properties
-**NOT for runtime enforcement** - All verification happens at compile time, in test builds only

### What This Library IS

This library **is**:

- **A type-level representation** - Makes your type system aware of declared use cases
-**A compile-time alarm** - Alerts you when changes might violate use case contracts
-**A documentation tool** - Use cases live in code, not separate documents
-**A proof of concept** - An experiment to see if type-level use cases provide value

You can think of it as: **"The compiler knows which use cases should exist, and will complain if you break their structure."**

It does **not** guarantee that your implementation is correct or complete, only that the structure exists.

---

## Possible Use Cases for This Library

### 1. LLM Context Enhancement

This library may be useful for Large Language Models (LLMs) to:
- Parse use case declarations directly from code
- Use use cases as a source of truth when generating or modifying code
- Better understand system intent and behavior contracts

### 2. Documentation Generation

Use case metadata (NAME, DESCRIPTION) is accessible at compile time and can be:
- Extracted for automatic documentation
- Used to generate diagrams
- Displayed in developer tools

### 3. Architectural Awareness

During refactoring or feature development:
- The type system alerts you when changes affect use cases
- Use case traits act as stable interfaces
- Easier to see which parts of the system implement which business logic

---

## The Solution

`typed_use_cases` makes use cases **first-class citizens in your type system**:

```rust
use typed_use_cases::{Actor, Entity, UseCase};

// 1. Declare actors and entities
#[derive(Actor)]
struct Authenticated { user_id: u64 }

#[derive(Entity)]
struct Cart {
    owner: Authenticated,
    items: Vec<u64>,
}

// 2. Declare use cases as named traits
trait AddItemToCart: UseCase<
    Authenticated,
    Cart,
    Input = Product,
    Output = Result<Cart, String>,
    Dependencies = (Box<dyn InventoryService>, Box<dyn CartRepository>),
> {}

// 3. Define your System type (application-specific, not part of the library)
struct System;  // Zero-sized type

// 4. Implement use cases on your System
impl UseCase<Authenticated, Cart> for System {
    const NAME: &'static str = "Add item to cart";
    const DESCRIPTION: &'static str = "An authenticated user can add a product to their cart";
    
    type Input = Product;
    type Output = Result<Cart, String>;
    type Dependencies = (Box<dyn InventoryService>, Box<dyn CartRepository>);

    fn satisfy(
        actor: Authenticated,
        cart: Cart,
        product: Product,
        deps: Self::Dependencies,
    ) -> Self::Output {
        let (inventory, cart_repo) = deps;
        // Implementation here...
        Ok(cart)
    }
}

impl AddItemToCart for System {}

// 5. Verify at compile time (in tests) that all use cases are implemented
typed_use_cases::implement_all_use_cases!(System: [
    AddItemToCart,
    // The compiler will complain if you declare a use case but forget to implement it
]);
```

**Result**: The type system is aware of your use cases. If you change a signature or remove an implementation, compilation fails in tests.

**Important**: The `System` type is **defined by you**, not by this library. It represents your application's use case implementations.

---

## How It Works

### Zero-Sized Type (ZST)

`System` is a **zero-sized type** — it occupies **0 bytes** at runtime:

```rust
assert_eq!(std::mem::size_of::<System>(), 0);
```

The `System` type exists purely for the compiler. It acts as a **witness** that your use cases are implemented.

### Compile-Time Verification

The `implement_all_use_cases!` macro expands only in test builds:

```rust
#[cfg(test)]
mod __use_cases_verification {
    static_assertions::assert_impl_all!(System: AddItemToCart);
    static_assertions::assert_impl_all!(System: Checkout);
    // ... one assertion per use case
}
```

This generates **zero runtime code**. The assertions run at compile time during `cargo test`.

### No Controller Changes

Your HTTP handlers and controllers remain unchanged. The library is purely a **compile-time concern**:

```rust
// Your controller code - unchanged
async fn add_to_cart_handler(req: Request) -> Response {
    let actor = authenticate(&req)?;
    let cart = load_cart(actor.user_id)?;
    let product = parse_product(&req)?;
    
    // Call the use case execution logic
    let updated_cart = add_item_to_cart_logic(actor, cart, product);
    
    save_cart(&updated_cart)?;
    Response::ok()
}
```

The `System` type and trait implementations serve as **documentation and verification**, not as runtime infrastructure.

---

## Install

Using cargo (recommended):

```bash
cargo add typed_use_cases
```

Or add to your `Cargo.toml`:

```toml
[dependencies]
typed_use_cases = "0.1"
```

That's it! No additional dependencies needed.

Note: `static_assertions` is only needed for the compile-time verification macro and does not appear in release builds.

---

## Concepts

### Actor

An **actor** is the initiator of a use case. Actors exist independently of any entity or action.

```rust
#[derive(Actor)]
struct Anonymous;

#[derive(Actor)]
struct Authenticated { user_id: u64 }
```

### Entity

An **entity** is what a use case operates on — the subject of the action.

```rust
#[derive(Entity)]
struct Catalog {
    products: Vec<Product>,
}

#[derive(Entity)]
struct Cart {
    owner: Authenticated,
    items: Vec<u64>,
}
```

### DependentEntity

A **dependent entity** is an entity whose existence is tied to a specific actor (e.g., a `Cart` belongs to an `Authenticated` user).

The `#[derive(Entity)]` macro automatically implements `DependentEntity<A>` if:
- A field named `owner` exists
- Its type is a single-segment path (e.g., `Authenticated`)

```rust
#[derive(Entity)]
struct Cart {
    owner: Authenticated,  // Automatically generates DependentEntity<Authenticated>
    items: Vec<u64>,
}
```

Manual implementation:

```rust
impl DependentEntity<Authenticated> for Cart {
    fn owner(&self) -> &Authenticated {
        &self.owner
    }
}
```

### UseCase

A **use case** IS the action. It's declared as a named trait that extends `UseCase<Actor, Entity>` and fixes all type parameters:

```rust
trait AddItemToCart: UseCase<
    Authenticated,       // Who initiates
    Cart,                // What it operates on
    Input = Product,     // Additional input data
    Output = Cart,       // What it produces
    Dependencies = (),   // External services needed
> {}
```

Each use case has compile-time metadata:

```rust
impl UseCase<Authenticated, Cart> for System {
    const NAME: &'static str = "Add item to cart";
    const DESCRIPTION: &'static str = "An authenticated user can add a product to their cart";
    
    // ... implementation
}
```

### System

A **zero-sized type defined by the user** (not by the library) that implements all use cases. It exists only for the compiler and occupies 0 bytes at runtime:

```rust
struct System;  // Your application defines this

impl UseCase<Anonymous, Catalog> for System { /* ... */ }
impl UseCase<Authenticated, Cart> for System { /* ... */ }
```

**Important**: The `System` type belongs to **your application**, not to the `typed_use_cases` library. Each application defines its own System type to implement its use cases.

### implement_all_use_cases!

A macro that verifies (at compile time, in test builds only) that `System` implements every declared use case:

```rust
typed_use_cases::implement_all_use_cases!(System: [
    BrowseCatalog,
    AddItemToCart,
    Checkout,
]);
```

If any use case is missing, **compilation fails** during `cargo test`.

---

## Example: E-Commerce

See [`examples/ecommerce.rs`](examples/ecommerce.rs) for a complete working example with:

- 3 actors: `Anonymous`, `Registered`, `Authenticated`
- 4 entities: `Catalog`, `Product`, `Cart`, `Order`
- 3 use cases: `BrowseCatalog`, `AddItemToCart`, `Checkout`

Run it with:

```bash
cargo run --example ecommerce
cargo test --example ecommerce
```

---

## Design Principles

- **Zero runtime overhead**: `System` is a ZST. No allocation, no dynamic dispatch.
- **Compile-time verification**: Use cases are checked at compile time, not runtime.
- **No framework lock-in**: Compatible with any web framework, DI container, or async runtime.
- **No boilerplate in production**: Controllers remain unchanged. This is purely additive.
- **Stable Rust**: No nightly features required.

---

## FAQ

### Does this work with async?

The `UseCase::execute` signature is synchronous by default. For async use cases:

1. Use the trait as a **contract witness** only (for compile-time verification)
2. Implement your actual async logic separately
3. Or wrap the execution in an async block

### Does this impose a dependency injection pattern?

No. `Dependencies` is a free associated type. Use `()` if you have no dependencies, or pass in any type you want (a struct, a trait object, a tuple of services, etc.).

### What about multiple use cases with the same Actor + Entity?

Each `UseCase<A, E>` implementation must be unique. If you have two use cases with the same actor and entity types, use different entity types (e.g., `Cart` vs `Order`) or create wrapper types.

### Does `static_assertions` appear in my release binary?

No. The `implement_all_use_cases!` macro expands only under `#[cfg(test)]`, and `static_assertions` is listed as a `# No additional dependencies needed!`.

---

## License

MIT

---

## Contributing

Contributions welcome! Please open an issue or pull request on GitHub.