Sha256: c5360b479f2f0eb9dd6fc97914d3af0c4eb92931d9abe53adad943cccefe11d4

Contents?: true

Size: 1.87 KB

Versions: 2

Compression:

Stored size: 1.87 KB

Contents

# frozen_string_literal: true

require_relative 'keywords'

module EasyTalk
  class InvalidPropertyNameError < StandardError; end

  #
  #= EasyTalk \SchemaDefinition
  # SchemaDefinition provides the methods for defining a schema within the define_schema block.
  # The @schema is a hash that contains the unvalidated schema definition for the model.
  # A SchemaDefinition instanace is the passed to the Builder.build_schema method to validate and compile the schema.
  class SchemaDefinition
    extend T::Sig
    extend T::AnyOf
    extend T::OneOf
    extend T::AllOf

    attr_reader :name, :schema

    def initialize(name, schema = {})
      @schema = schema
      @name = name
    end

    EasyTalk::KEYWORDS.each do |keyword|
      define_method(keyword) do |*values|
        @schema[keyword] = values.size > 1 ? values : values.first
      end
    end

    def compose(*subschemas)
      @schema[:subschemas] ||= []
      @schema[:subschemas] += subschemas
    end

    sig do
      params(name: T.any(Symbol, String), type: T.untyped, constraints: T.untyped, blk: T.nilable(T.proc.void)).void
    end
    def property(name, type, constraints = {}, &blk)
      validate_property_name(name)
      @schema[:properties] ||= {}

      if block_given?
        property_schema = SchemaDefinition.new(name)
        property_schema.instance_eval(&blk)

        @schema[:properties][name] = {
          type:,
          constraints:,
          properties: property_schema
        }
      else
        @schema[:properties][name] = { type:, constraints: }
      end
    end

    def validate_property_name(name)
      return if name.to_s.match?(/^[A-Za-z_][A-Za-z0-9_]*$/)

      raise InvalidPropertyNameError,
            "Invalid property name '#{name}'. Must start with letter/underscore and contain only letters, numbers, underscores"
    end

    def optional?
      @schema[:optional]
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
easy_talk-1.0.2 lib/easy_talk/schema_definition.rb
easy_talk-1.0.1 lib/easy_talk/schema_definition.rb