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 style_name.ex
Raw

lib/sashite/snn/style_name.ex

defmodule Sashite.Snn.StyleName do
@moduledoc """
Represents a validated SNN (Style Name Notation) style name.
A StyleName encodes a single attribute:
- `name`: the validated SNN string (PascalCase with optional numeric suffix)
StyleName structs are immutable. The name is validated upon creation.
## Examples
iex> snn = Sashite.Snn.StyleName.new("Chess")
iex> snn.name
"Chess"
iex> snn = Sashite.Snn.StyleName.new("Chess960")
iex> Sashite.Snn.StyleName.to_string(snn)
"Chess960"
See: https://sashite.dev/specs/snn/1.0.0/
"""
alias Sashite.Snn.Parser
@enforce_keys [:name]
defstruct [:name]
@typedoc "An SNN style name struct"
@type t :: %__MODULE__{
name: String.t()
}
# ==========================================================================
# Constructor
# ==========================================================================
@doc """
Creates a new StyleName with the given name.
## Parameters
- `name` - The SNN string (must be valid PascalCase format)
## Returns
A new `%StyleName{}` struct.
## Raises
- `ArgumentError` if name is invalid
## Examples
iex> snn = Sashite.Snn.StyleName.new("Chess")
iex> snn.name
"Chess"
iex> snn = Sashite.Snn.StyleName.new("Chess960")
iex> snn.name
"Chess960"
iex> Sashite.Snn.StyleName.new("chess")
** (ArgumentError) invalid format
iex> Sashite.Snn.StyleName.new("")
** (ArgumentError) empty input
"""
@spec new(String.t()) :: t()
def new(name) do
case Parser.parse(name) do
{:ok, validated_name} ->
%__MODULE__{name: validated_name}
{:error, reason} ->
raise ArgumentError, error_message(reason)
end
end
# ==========================================================================
# String Conversion
# ==========================================================================
@doc """
Returns the SNN string representation.
## Examples
iex> snn = Sashite.Snn.StyleName.new("Chess")
iex> Sashite.Snn.StyleName.to_string(snn)
"Chess"
iex> snn = Sashite.Snn.StyleName.new("Xiangqi")
iex> Sashite.Snn.StyleName.to_string(snn)
"Xiangqi"
"""
@spec to_string(t()) :: String.t()
def to_string(%__MODULE__{name: name}) do
name
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
defimpl String.Chars, for: Sashite.Snn.StyleName do
def to_string(style_name) do
Sashite.Snn.StyleName.to_string(style_name)
end
end
defimpl Inspect, for: Sashite.Snn.StyleName do
def inspect(style_name, _opts) do
"#Sashite.Snn.StyleName<#{Sashite.Snn.StyleName.to_string(style_name)}>"
end
end