Module: SpecForge::Type

Defined in:
lib/spec_forge/type.rb

Overview

Utilities for converting between Ruby classes and type strings

Type provides bidirectional conversion between Ruby types (Integer, String, etc.) and their string representations ("integer", "string", etc.) used in YAML schema definitions. Supports nullable types with the "?" prefix and optional fields with the "*" prefix.

Constant Summary collapse

CLASS_TO_STRING =

Mapping from Ruby classes to type string names

Returns:

  • (Hash{Class => String})
{
  Integer => "integer",
  Float => "float",
  String => "string",
  Hash => "hash",
  Array => "array",
  TrueClass => "boolean",
  FalseClass => "boolean",
  NilClass => "null"
}.freeze
STRING_TO_CLASS =

Mapping from type string names to Ruby classes

Returns:

  • (Hash{String => Array<Class>})
{
  "string" => [String],
  "number" => [Integer, Float],
  "numeric" => [Integer, Float],
  "integer" => [Integer],
  "float" => [Float],
  "bool" => [TrueClass, FalseClass],
  "boolean" => [TrueClass, FalseClass],
  "array" => [Array],
  "hash" => [Hash],
  "object" => [Hash],
  "null" => [NilClass],
  "nil" => [NilClass]
}.freeze

Class Method Summary collapse

Class Method Details

.from_string(input) ⇒ Hash

Converts a type string to a hash containing Ruby classes and optional flag

Supports nullable types with the "?" prefix (e.g., "?string") and optional fields with the "*" prefix (e.g., "string"). Flags can be combined in any order (e.g., "?string" or "?*string").

Examples:

Type.from_string("integer")   # => { types: [Integer], optional: false }
Type.from_string("?string")   # => { types: [String, NilClass], optional: false }
Type.from_string("*string")   # => { types: [String], optional: true }
Type.from_string("*?string")  # => { types: [String, NilClass], optional: true }

Parameters:

  • input (String)

    The type string (e.g., "integer", "?string", "*?boolean")

Returns:

  • (Hash)

    Hash with :types (Array) and :optional (Boolean)

Raises:

  • (ArgumentError)

    If input is nil or unknown type



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/spec_forge/type.rb', line 65

def from_string(input)
  raise ArgumentError, "Input is nil" if input.nil?

  # Extract flags from start of string
  potential_flags = input[..2]
  optional = potential_flags.include?("*")
  nullable = potential_flags.include?("?")

  if optional || nullable
    offset = [optional, nullable].count(true)
    input = input[offset..]
  end

  types = STRING_TO_CLASS[input.downcase]&.dup

  if types.nil?
    raise ArgumentError,
      "Unknown type: #{input.in_quotes}. Valid types: string, number/numeric, integer, float, boolean/bool, array, hash/object, null/nil"
  end

  # Add NilClass if nullable
  types << NilClass if nullable
  types.uniq!

  {types:, optional:}
end

.to_string(*types) ⇒ String+

Converts Ruby classes to their type string representation

Handles nullable types (includes NilClass) by adding "?" prefix. Normalizes boolean types (TrueClass/FalseClass) to single "boolean".

Examples:

Type.to_string(Integer)                    # => "integer"
Type.to_string(String, NilClass)           # => "?string"
Type.to_string(TrueClass, FalseClass)      # => "boolean"
Type.to_string(Integer, String)            # => ["integer", "string"]

Parameters:

  • types (Array<Class>)

    One or more Ruby classes

Returns:

  • (String, Array<String>)

    Type string or array if multiple distinct types



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/spec_forge/type.rb', line 108

def to_string(*types)
  types = types.map { |k| CLASS_TO_STRING[k] }

  null = CLASS_TO_STRING[NilClass] # Just in case the name changes
  if types.delete(null)
    # We removed the nil above, no other types means this is just nil. No need to continue processing
    return null if types.empty?

    types.map! { |t| "?#{t}" }
  end

  # Remove "boolean", "boolean" that happens with TrueClass/FalseClass
  types.uniq!

  (types.size == 1) ? types.first : types
end