README.md

# hand.ex

[![Hex.pm](https://img.shields.io/hexpm/v/sashite_hand.svg)](https://hex.pm/packages/sashite_hand)
[![Docs](https://img.shields.io/badge/hex-docs-blue.svg)](https://hexdocs.pm/sashite_hand)
[![License](https://img.shields.io/hexpm/l/sashite_hand.svg)](https://github.com/sashite/hand.ex/blob/main/LICENSE)

> **HAND** (Hold And Notation Designator) implementation for Elixir.

## Overview

This library implements the [HAND Specification v1.0.0](https://sashite.dev/specs/hand/1.0.0/).

## Installation

Add `sashite_hand` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:sashite_hand, "~> 1.0"}
  ]
end
```

## Usage

### Parsing (String → Atom)

Convert a HAND string into an atom.

```elixir
# Standard parsing (returns {:ok, atom} or {:error, reason})
{:ok, :"*"} = Sashite.Hand.parse("*")

# Bang version (raises on error)
:"*" = Sashite.Hand.parse!("*")

# Invalid input
{:error, :invalid_hand_notation} = Sashite.Hand.parse("e4")
{:error, :invalid_hand_notation} = Sashite.Hand.parse("")
```

### Validation

```elixir
# Boolean check
Sashite.Hand.valid?("*")   # => true
Sashite.Hand.valid?("e4")  # => false
Sashite.Hand.valid?("")    # => false
Sashite.Hand.valid?(nil)   # => false
```

### Using the Notation Constant

```elixir
# Access the HAND notation atom
Sashite.Hand.notation()  # => :"*"

# Convert to string when needed
Atom.to_string(Sashite.Hand.notation())  # => "*"
```

## API Reference

### Constants

```elixir
Sashite.Hand.notation()  # => :"*"
```

### Parsing

```elixir
# Parses a HAND string into an atom.
# Returns {:ok, :"*"} or {:error, :invalid_hand_notation}.
@spec parse(String.t()) :: {:ok, atom()} | {:error, :invalid_hand_notation}

# Parses a HAND string into an atom.
# Raises ArgumentError if the string is not valid.
@spec parse!(String.t()) :: atom()
```

### Validation

```elixir
# Reports whether string is a valid HAND notation.
@spec valid?(term()) :: boolean()
```

### Errors

| Error | Cause |
|-------|-------|
| `{:error, :invalid_hand_notation}` | Input is not exactly `*` |
| `ArgumentError` | Bang function with invalid input |

## Design Principles

- **Atom-based**: Notation represented as Elixir atom for identity semantics
- **Minimal**: Single constant and three functions
- **Elixir idioms**: `{:ok, _}` / `{:error, _}` tuples, `parse!` bang variant
- **Strict validation**: Only the `*` character is accepted
- **No dependencies**: Pure Elixir standard library only

## Related Specifications

- [Game Protocol](https://sashite.dev/game-protocol/) — Conceptual foundation
- [HAND Specification](https://sashite.dev/specs/hand/1.0.0/) — Official specification
- [CELL Specification](https://sashite.dev/specs/cell/1.0.0/) — Complementary notation for Board squares

## License

Available as open source under the [Apache License 2.0](https://opensource.org/licenses/Apache-2.0).