uy 0.3.0

A typesafe, flexible, simple, and user-friendly unit system library for Rust that has good error messages.
Documentation
# uy - Type-Safe Units Library for Rust

## Project Overview

`uy` is a compile-time dimensional analysis library that encodes both units AND scale (power of ten) into Rust's type system. This prevents unit errors at compile time with clear error messages.

## Architecture

### Core Files

- **`src/lib.rs`** - Core library with `Unit` trait, `TenTo<N>`, `Mul`/`Div` combinators, and the `power_of_ten_unit_system!` macro
- **`src/quantity.rs`** - The `Quantity<T, U>` wrapper type
- **`src/si.rs`** - SI unit system: base units, prefixes, derived units, and quantity type aliases
- **`src/inner.rs`** - Internal type-level arithmetic bridging const generics to typenum

### Module Structure

```
si/
├── units/           # Raw unit types (m, s, kg, N, Hz, meters_per_second, etc.)
│   └── derived/     # Derived unit types
├── prefixes/        # Scale prefixes (milli, kilo, etc.)
└── (top-level)      # Quantity type aliases (meters<T>, seconds<T>, newtons<T>, etc.)
```

**Important**: The `si` module has two layers:
- `si::units::*` - Raw unit types for use with `Quantity<T, U>` and prefixes
- `si::*` (top-level) - Quantity type aliases like `si::meters<T>` = `Quantity<T, units::m>`

### Key Design Pattern

All derived and compound units are just type aliases to `Mul`/`Div` combinations. Prefixes are `Mul<U, TenTo<N>>`. This means the system is extensible without special cases.

```rust
pub type Hz = Div<unitless, s>;
pub type N = Mul<kg, Div<m, Mul<s, s>>>;
pub type milli<U> = Mul<U, TenTo<-3>>;
```

## Guidelines

### Documentation

- **Describe patterns and structure, not exhaustive lists.** Enumerating every unit, prefix, or variant creates maintenance burden and goes stale. Instead, explain the underlying system so users can discover specifics via IDE or `cargo doc`.
- Keep architecture documentation in sync when refactoring module structure.

### Rust Type System

- **Type aliases only exist in the type namespace.** A `type Foo = Bar;` cannot be used as a value, even if `Bar` is a unit struct. This is a fundamental Rust limitation, not a bug.
- When designing APIs, consider whether users need type-level constructs (for generic bounds) or value-level constructs (for expressions).

### Testing

- Use inline `#[cfg(test)]` modules, not separate test files.
- **Test the underlying mechanics, not every instance.** If the math/logic is tested once, don't redundantly test every combination that uses it.
- Prefer testing behavior over testing specific types.

### Code Style

- `#[repr(transparent)]` for zero-cost wrappers
- Const generics bridged to typenum for type-level arithmetic
- Exponent range: -30 to +30 (SI prefix range)

## Build Commands

```bash
cargo build          # Build
cargo test           # Run tests
cargo doc --open     # Generate docs
```