Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cursorrules
8 changes: 8 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@ env:

jobs:
build:
strategy:
matrix:
rust: ["1.71.0", "stable"]
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
- name: Build
run: cargo build --verbose
- name: Run tests
Expand Down
1 change: 1 addition & 0 deletions .junie/guidelines.md
19 changes: 19 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
style_edition = "2021"
max_width = 120

group_imports = "StdExternalCrate"

normalize_doc_attributes = true
normalize_comments = true
wrap_comments = true

reorder_modules = false

reorder_impl_items = true

where_single_line = true
fn_params_layout = "Compressed"
fn_single_line = true

use_field_init_shorthand = true
use_try_shorthand = true
51 changes: 51 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Agent Instructions

## Project Overview

This repository contains the `unit-enum` Rust crate, a procedural macro (`#[derive(UnitEnum)]`) for enums that are primarily composed of unit variants. It generates utility methods such as `name`, `ordinal`, `from_ordinal`, `discriminant`, `from_discriminant`, `len`, and `values`, while respecting the enum's `#[repr]` and optionally supporting a single `"other"` catch‑all variant.

## File Structure and Organization

- **AGENTS.md**: Root instruction file for AI agents (this file). Also used via symlinks by other tools.
- **README.md**: Human-facing crate documentation and quick-start examples.
- **Cargo.toml**: Crate metadata, dependencies, and configuration (`proc-macro = true`).
- **src/lib.rs**: Implementation of the `UnitEnum` derive macro and its validation / codegen logic.
- **src/lib.md**: Crate-level Rustdoc included into the library docs; keep examples and text in sync with `README.md`.
- **examples/**: Small runnable binaries (`example.rs`, `example_other.rs`) that demonstrate typical usage, including the optional `"other"` variant.
- **.github/workflows/rust.yml**: GitHub Actions workflow for CI (build/tests).
- **CHANGELOG.md**: Human-maintained change log; follow existing style when documenting externally visible changes.
- **LICENSE-MIT**, **LICENSE-APACHE**: Dual licensing information.
- **agents/**: Reserved for generic, reusable, and versioned instruction documents. Do not modify from within this project; treat contents (if any) as read-only.

## Symbolic Links

This AGENTS.md file is symlinked for compatibility with different AI agents:

- `CLAUDE.md` → `AGENTS.md`
- `.junie/guidelines.md` → `AGENTS.md`
- `GEMINI.md` → `AGENTS.md`
- `.cursorrules` → `AGENTS.md`

Any changes you make here automatically apply to those entrypoints; keep instructions tool-agnostic.

## Development Guidelines

### Code Organization

- Maintain a clear separation between agent instructions (`AGENTS.md`) and human documentation (`README.md`, `CHANGELOG.md`, crate docs in `src/lib.md`).
- Keep instructions dense, unambiguous, and optimized for AI processing (short sections, explicit bullets, minimal prose).
- When modifying macro behavior in `src/lib.rs`, also:
- Update or add examples in `src/lib.md`, `README.md`, and `examples/` as appropriate.
- Preserve the documented semantics of generated methods (`name`, `ordinal`, `discriminant`, etc.) unless the change is intentionally breaking and coordinated with versioning.
- Do not modify files under `agents/` from this repository; treat them as shared, versioned guidance.

### Rust & Testing

- Use `cargo test` (and, if relevant, `cargo test --examples`) to validate changes; this runs doctests in `src/lib.md` and `README.md` as well as any unit tests.
- Prefer adding or updating doctests and examples when fixing bugs or changing behavior in the derive macro.
- Avoid introducing public API changes without updating documentation and, when applicable, bumping versions and changelog entries in coordination with maintainers.

### File Management

- Only modify `AGENTS.md` directly; its symbolic links (`CLAUDE.md`, `.junie/guidelines.md`, `GEMINI.md`, `.cursorrules`) should not be edited independently.
- After making non-trivial changes to the crate or its structure, update this `AGENTS.md` to reflect the current project state so future agents have accurate context.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Version 1.5.0 (2026-03-04)

### Added

- Make `name`, `ordinal`, `from_ordinal`, `discriminant`, `from_discriminant`, and `len` const-friendly by generating them as `const fn`
- Document the minimum supported Rust version (MSRV) as Rust 1.71 and add a section describing const usage in the documentation

## Version 1.4.3 (2025-05-20)

### Fixed
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
47 changes: 0 additions & 47 deletions Cargo.lock

This file was deleted.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[package]
name = "unit-enum"
version = "1.4.3"
version = "1.5.0"
authors = ["Renaud Denis <mail@renauddenis.com>"]
description = "A procedural macro for deriving ordinal methods in unit-like enums for Rust."
license = "MIT OR Apache-2.0"
repository = "https://github.com/tylium/unit-enum"
keywords = ["enum", "derive", "proc_macro", "procmacro"]
edition = "2021"
readme = "README.md"
rust-version = "1.71"

[lib]
proc-macro = true
Expand Down
1 change: 1 addition & 0 deletions GEMINI.md
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ consisting of unit variants. This macro simplifies working with such enums by pr
## Supported Enum Types

The macro supports two types of enums:

1. Enums with only unit variants
2. Enums with unit variants plus one "other" variant for handling undefined discriminant values

Expand All @@ -29,9 +30,13 @@ Add the following to your `Cargo.toml`:

```toml
[dependencies]
unit-enum = "1.4.1"
unit-enum = "1"
```

## Minimum Supported Rust Version (MSRV)

This crate supports **Rust 1.71+**.

## Quick Start

### Basic Usage (Unit Variants Only)
Expand Down Expand Up @@ -77,6 +82,34 @@ fn main() {
}
```

### Const-friendly methods

Because all enum information is known at compile time, most of the generated
methods are available as `const fn` and can be used in constant contexts.

```rust
use unit_enum::UnitEnum;

#[derive(Debug, Clone, Copy, PartialEq, UnitEnum)]
enum Status {
Active = 1,
Pending, // 2
Inactive = 5,
}

const STATUS_COUNT: usize = Status::len();
const FIRST_NAME: &str = Status::Active.name();
const FROM_ORDINAL: Option<Status> = Status::from_ordinal(1);
const FROM_DISCRIMINANT: Option<Status> = Status::from_discriminant(1);

fn main() {
assert_eq!(STATUS_COUNT, 3);
assert_eq!(FIRST_NAME, "Active");
assert_eq!(FROM_ORDINAL, Some(Status::Pending));
assert_eq!(FROM_DISCRIMINANT, Some(Status::Active));
}
```

### Usage with "Other" Variant

```rust
Expand Down Expand Up @@ -114,6 +147,7 @@ fn main() {
## Discriminant Types

The crate respects the enum's `#[repr]` attribute to determine the type of discriminant values. Supported types include:

- `#[repr(i8)]`, `#[repr(i16)]`, `#[repr(i32)]`, `#[repr(i64)]`, `#[repr(i128)]`
- `#[repr(u8)]`, `#[repr(u16)]`, `#[repr(u32)]`, `#[repr(u64)]`, `#[repr(u128)]`

Expand Down Expand Up @@ -141,6 +175,7 @@ enum LargeEnum {
## Requirements for "Other" Variant

When using an "other" variant, the following requirements must be met:

- The enum must have a `#[repr(type)]` attribute
- Only one variant can be marked with `#[unit_enum(other)]`
- The "other" variant must have exactly one unnamed field matching the repr type
Expand Down
Empty file added agents/.gitkeep
Empty file.
2 changes: 1 addition & 1 deletion examples/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ fn main() {
Color::values().collect::<Vec<_>>(),
vec![Color::Red, Color::Green, Color::Blue]
);
}
}
2 changes: 1 addition & 1 deletion examples/example_other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ fn main() {
Color::values().collect::<Vec<_>>(),
vec![Color::Red, Color::Green, Color::Blue]
);
}
}
33 changes: 33 additions & 0 deletions src/lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,34 @@ assert_eq!(
);
```

## Const-friendly methods

Because all enum information is known at compile time, most of the generated
methods are available as `const fn` and can be used in constant contexts.

```rust
use unit_enum::UnitEnum;

#[derive(Debug, Clone, Copy, PartialEq, UnitEnum)]
enum Status {
Active = 1,
Pending, // 2
Inactive = 5,
}

const STATUS_COUNT: usize = Status::len();
const FIRST_NAME: &str = Status::Active.name();
const FROM_ORDINAL: Option<Status> = Status::from_ordinal(1);
const FROM_DISCRIMINANT: Option<Status> = Status::from_discriminant(1);

fn main() {
assert_eq!(STATUS_COUNT, 3);
assert_eq!(FIRST_NAME, "Active");
assert_eq!(FROM_ORDINAL, Some(Status::Pending));
assert_eq!(FROM_DISCRIMINANT, Some(Status::Active));
}
```

## Usage with "Other" Variant

The macro also supports enums with an additional "other" variant for handling undefined discriminant values:
Expand Down Expand Up @@ -113,6 +141,11 @@ Supported types include:
If no `#[repr]` is specified, `i32` is used by default. Note that when using an "other" variant,
the `#[repr]` attribute is required and must match the type of the "other" variant's field.

## Minimum Supported Rust Version (MSRV)

This crate supports **Rust 1.71+**.
All const-friendly methods described above are available on this MSRV.

## Requirements

For basic unit-only enums:
Expand Down
Loading
Loading