# cell.ex
[](https://hex.pm/packages/sashite_cell)
[](https://hexdocs.pm/sashite_cell)
[](https://github.com/sashite/cell.ex/blob/main/LICENSE)
> **CELL** (Coordinate Encoding for Layered Locations) implementation for Elixir.
## Overview
This library implements the [CELL Specification v1.0.0](https://sashite.dev/specs/cell/1.0.0/).
### Implementation Constraints
| Constraint | Value | Rationale |
|------------|-------|-----------|
| Max dimensions | 3 | Sufficient for 1D, 2D, 3D boards |
| Max index value | 255 | Covers 256×256×256 boards |
| Max string length | 7 | `"iv256IV"` (max for all dimensions at 255) |
These constraints enable bounded memory usage and safe parsing.
## Installation
Add `sashite_cell` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:sashite_cell, "~> 2.0"}
]
end
```
## Usage
### Parsing (String → Indices)
Convert a CELL string into a tuple of indices.
```elixir
# Standard parsing (returns {:ok, tuple} or {:error, message})
{:ok, indices} = Sashite.Cell.to_indices("e4")
indices # => {4, 3}
# 3D coordinate
{:ok, indices} = Sashite.Cell.to_indices("a1A")
indices # => {0, 0, 0}
# Bang version (raises on error)
Sashite.Cell.to_indices!("e4") # => {4, 3}
```
### Formatting (Indices → String)
Convert a tuple of indices back to a CELL string.
```elixir
# Standard formatting (returns {:ok, string} or {:error, message})
{:ok, coord} = Sashite.Cell.from_indices({4, 3})
coord # => "e4"
# Bang version
Sashite.Cell.from_indices!({0, 0, 0}) # => "a1A"
Sashite.Cell.from_indices!({2, 2, 2}) # => "c3C"
```
### Validation
```elixir
# Boolean check
Sashite.Cell.valid?("e4") # => true
Sashite.Cell.valid?("a0") # => false
```
### Accessing Coordinate Data
```elixir
indices = Sashite.Cell.to_indices!("e4")
# Get dimensions count
tuple_size(indices) # => 2
# Access individual index
elem(indices, 0) # => 4
elem(indices, 1) # => 3
# Round-trip conversion
"e4" |> Sashite.Cell.to_indices!() |> Sashite.Cell.from_indices!() # => "e4"
```
## API Reference
### Constants
```elixir
Sashite.Cell.Coordinate.max_dimensions() # => 3
Sashite.Cell.Coordinate.max_index_value() # => 255
Sashite.Cell.Coordinate.max_string_length() # => 7
```
### Parsing
```elixir
@spec to_indices(String.t()) :: {:ok, tuple()} | {:error, String.t()}
def to_indices(string)
@spec to_indices!(String.t()) :: tuple()
def to_indices!(string)
```
Converts a CELL string to a tuple of 0-indexed integers.
The bang version raises `ArgumentError` on invalid input.
### Formatting
```elixir
@spec from_indices(tuple()) :: {:ok, String.t()} | {:error, String.t()}
def from_indices(indices)
@spec from_indices!(tuple()) :: String.t()
def from_indices!(indices)
```
Converts a tuple of 0-indexed integers to a CELL string.
The bang version raises `ArgumentError` on invalid input.
### Validation
```elixir
@spec valid?(String.t()) :: boolean()
def valid?(string)
```
Reports whether the string is a valid CELL coordinate.
### Errors
All parsing and validation errors return `{:error, message}` tuples or raise `ArgumentError` for bang versions:
| Message | Cause |
|---------|-------|
| `"empty input"` | String length is 0 |
| `"input exceeds 7 characters"` | String too long |
| `"must start with lowercase letter"` | Invalid first character |
| `"unexpected character"` | Character violates the cyclic sequence |
| `"leading zero"` | Numeric part starts with '0' |
| `"exceeds 3 dimensions"` | More than 3 dimensions |
| `"index exceeds 255"` | Decoded value out of range |
## Design Principles
- **Elixir idioms**: `{:ok, value}` / `{:error, reason}` tuples with bang variants
- **Tuple-based coordinates**: Native Elixir tuples for indices
- **Predicate functions**: `valid?/1` follows Elixir naming conventions
- **Immutable by default**: All functions return new values
- **No dependencies**: Pure Elixir standard library only
## Related Specifications
- [Game Protocol](https://sashite.dev/game-protocol/) — Conceptual foundation
- [CELL Specification](https://sashite.dev/specs/cell/1.0.0/) — Official specification
- [CELL Examples](https://sashite.dev/specs/cell/1.0.0/examples/) — Usage examples
## License
Available as open source under the [Apache License 2.0](https://opensource.org/licenses/Apache-2.0).