SIN (Style Identifier Notation) implementation for Ruby.
This library implements the SIN Specification v1.0.0.
# In your Gemfile
gem "sashite-sin"Or install manually:
gem install sashite-sinConvert a SIN string into an Identifier object.
require "sashite/sin"
# Standard parsing (raises on error)
sin = Sashite::Sin.parse("C")
sin.style # => :C
sin.side # => :first
# Lowercase indicates second player
sin = Sashite::Sin.parse("c")
sin.style # => :C
sin.side # => :second
# Invalid input raises ArgumentError
Sashite::Sin.parse("") # => raises ArgumentError
Sashite::Sin.parse("CC") # => raises ArgumentErrorConvert an Identifier back to a SIN string.
# From Identifier object
sin = Sashite::Sin::Identifier.new(:C, :first)
sin.to_s # => "C"
sin = Sashite::Sin::Identifier.new(:C, :second)
sin.to_s # => "c"# Boolean check
Sashite::Sin.valid?("C") # => true
Sashite::Sin.valid?("c") # => true
Sashite::Sin.valid?("") # => false
Sashite::Sin.valid?("CC") # => false
Sashite::Sin.valid?("1") # => falsesin = Sashite::Sin.parse("C")
# Get attributes
sin.style # => :C
sin.side # => :first
# Get string component
sin.letter # => "C"All transformations return new immutable Identifier objects.
sin = Sashite::Sin.parse("C")
# Side transformation
sin.flip.to_s # => "c"
# Attribute changes
sin.with_style(:S).to_s # => "S"
sin.with_side(:second).to_s # => "c"sin = Sashite::Sin.parse("C")
# Side queries
sin.first_player? # => true
sin.second_player? # => false
# Comparison queries
other = Sashite::Sin.parse("c")
sin.same_style?(other) # => true
sin.same_side?(other) # => false# Identifier represents a parsed SIN identifier with style and side.
class Sashite::Sin::Identifier
# Creates an Identifier from style and side.
# Raises ArgumentError if attributes are invalid.
#
# @param style [Symbol] Style abbreviation (:A through :Z)
# @param side [Symbol] Player side (:first or :second)
# @return [Identifier]
def initialize(style, side)
# Returns the style as an uppercase symbol.
#
# @return [Symbol]
def style
# Returns the player side.
#
# @return [Symbol] :first or :second
def side
# Returns the SIN string representation.
#
# @return [String]
def to_s
endSashite::Sin::Identifier::VALID_STYLES # => [:A, :B, ..., :Z]
Sashite::Sin::Identifier::VALID_SIDES # => [:first, :second]# Parses a SIN string into an Identifier.
# Raises ArgumentError if the string is not valid.
#
# @param string [String] SIN string
# @return [Identifier]
# @raise [ArgumentError] if invalid
def Sashite::Sin.parse(string)# Reports whether string is a valid SIN identifier.
#
# @param string [String] SIN string
# @return [Boolean]
def Sashite::Sin.valid?(string)All transformations return new Sashite::Sin::Identifier objects:
# Side transformation
def flip # => Identifier
# Attribute changes
def with_style(style) # => Identifier
def with_side(side) # => Identifier# Side queries
def first_player? # => Boolean
def second_player? # => Boolean
# Comparison queries
def same_style?(other) # => Boolean
def same_side?(other) # => BooleanAll parsing and validation errors raise ArgumentError with descriptive messages:
| Message | Cause |
|---|---|
"empty input" |
String length is 0 |
"input exceeds 1 character" |
String too long |
"must be a letter" |
Character is not A-Z or a-z |
- Bounded values: Explicit validation of styles and sides
- Object-oriented:
Identifierclass enables methods and encapsulation - Ruby idioms:
valid?predicate,to_sconversion,ArgumentErrorfor invalid input - Immutable identifiers: All transformations return new objects
- No dependencies: Pure Ruby standard library only
- Game Protocol — Conceptual foundation
- SIN Specification — Official specification
- SIN Examples — Usage examples
Available as open source under the Apache License 2.0.