Packages

SNN (Style Name Notation) implementation for Elixir. Provides a rule-agnostic format for identifying game styles in abstract strategy board games with immutable style name structs and functional programming principles.

Current section

Files

Jump to
sashite_snn lib sashite_snn.ex
Raw

lib/sashite_snn.ex

defmodule Sashite.Snn do
@moduledoc """
SNN (Style Name Notation) implementation for Elixir.
SNN provides a human-readable naming system for game styles (Piece Styles)
in abstract strategy board games. It uses PascalCase names with optional
numeric suffixes to identify movement traditions or game variants.
## Examples
iex> {:ok, snn} = Sashite.Snn.parse("Chess")
iex> snn.name
"Chess"
iex> snn = Sashite.Snn.parse!("Chess960")
iex> snn.name
"Chess960"
iex> Sashite.Snn.valid?("Shogi")
true
iex> Sashite.Snn.valid?("shogi")
false
See: https://sashite.dev/specs/snn/1.0.0/
"""
alias Sashite.Snn.Parser
alias Sashite.Snn.StyleName
@doc """
Parses an SNN string into a StyleName.
## Parameters
- `input` - The SNN string to parse
## Returns
- `{:ok, %StyleName{}}` on success
- `{:error, reason}` on failure
## Error Reasons
- `:empty_input` - String length is 0
- `:input_too_long` - String exceeds 32 characters
- `:invalid_format` - Does not match SNN format
## Examples
iex> {:ok, snn} = Sashite.Snn.parse("Chess")
iex> snn.name
"Chess"
iex> {:ok, snn} = Sashite.Snn.parse("Chess960")
iex> snn.name
"Chess960"
iex> Sashite.Snn.parse("")
{:error, :empty_input}
iex> Sashite.Snn.parse("chess")
{:error, :invalid_format}
iex> Sashite.Snn.parse("123")
{:error, :invalid_format}
"""
@spec parse(String.t()) :: {:ok, StyleName.t()} | {:error, atom()}
def parse(input) do
case Parser.parse(input) do
{:ok, name} ->
{:ok, %StyleName{name: name}}
{:error, reason} ->
{:error, reason}
end
end
@doc """
Parses an SNN string into a StyleName, raising on error.
## Parameters
- `input` - The SNN string to parse
## Returns
A `%StyleName{}` struct.
## Raises
- `ArgumentError` if the input is invalid
## Examples
iex> snn = Sashite.Snn.parse!("Chess")
iex> snn.name
"Chess"
iex> snn = Sashite.Snn.parse!("Shogi")
iex> snn.name
"Shogi"
iex> Sashite.Snn.parse!("")
** (ArgumentError) empty input
iex> Sashite.Snn.parse!("chess")
** (ArgumentError) invalid format
"""
@spec parse!(String.t()) :: StyleName.t()
def parse!(input) do
case parse(input) do
{:ok, style_name} ->
style_name
{:error, reason} ->
raise ArgumentError, error_message(reason)
end
end
@doc """
Reports whether the input is a valid SNN string.
## Examples
iex> Sashite.Snn.valid?("Chess")
true
iex> Sashite.Snn.valid?("Chess960")
true
iex> Sashite.Snn.valid?("A")
true
iex> Sashite.Snn.valid?("")
false
iex> Sashite.Snn.valid?("chess")
false
iex> Sashite.Snn.valid?(nil)
false
"""
@spec valid?(term()) :: boolean()
def valid?(input) do
Parser.valid?(input)
end
# ==========================================================================
# Private Helpers
# ==========================================================================
defp error_message(:empty_input), do: "empty input"
defp error_message(:input_too_long), do: "input too long"
defp error_message(:invalid_format), do: "invalid format"
end