class Taipo::TypeElement

An element representing a type (including children and constraints)

@since 1.0.0 @api private

Attributes

children[RW]

The children for this element

@since 1.4.0 @api private

constraints[R]

The constraints for this element

@since 1.0.0 @api private

name[RW]

The name of the element

@since 1.0.0 @api private

Public Class Methods

new(name:, children: nil, constraints: nil) click to toggle source

Initialize a new type element

@param name [String] the name of this type @param children [Taipo::TypeElement::Children|NilClass] the children for

this type

@param constraints [Array<Taipo::TypeElement::Constraints>|NilClass] the

constraints for this type

@raise [::TypeError] if name, children or constraints was of the

wrong type

@raise [::ArgumentError] if name, children or constraints was

blank/empty

@since 1.0.0 @api private

# File lib/taipo/type_element.rb, line 48
def initialize(name:, children: nil, constraints: nil)
  msg = 'Argument name was not a String.'
  raise ::TypeError, msg unless name.is_a? String
  msg = 'Argument name was an empty string.'
  raise ::ArgumentError if name.empty?

  msg = 'Argument children was not a Taipo::TypeElement::Children.'
  raise ::TypeError unless children.nil? ||
    children.is_a?(Taipo::TypeElement::Children)
  msg = 'Argument children was empty.'
  raise ::ArgumentError if !children.nil? && children.empty?

  msg = 'Argument constraints was not a Taipo::TypeElement::Constraints.'
  raise ::TypeError unless constraints.nil? ||
    constraints.is_a?(Taipo::TypeElement::Constraints)
  msg = 'Argument constraints was empty.'
  raise ::ArgumentError if !constraints.nil? && constraints.empty?

  @name = name
  @children = children
  @constraints = constraints
end

Public Instance Methods

==(comp) click to toggle source

Compare the element with comp

@param comp [Taipo::TypeElement] the comparison

@return [Boolean] the result

@raise [::TypeError] if comp is of the wrong type

@since 1.0.0 @api private

# File lib/taipo/type_element.rb, line 81
def ==(comp)
  msg = 'Object to be compared must be of type Taipo::TypeElement.'
  raise ::TypeError, msg unless comp.is_a? Taipo::TypeElement

  @name == comp.name && @children == comp.children
end
constraints=(csts) click to toggle source

Set the element's constraints to csts

@param csts [Taipo::TypeElement::Constraints] the constraints

@raise [::TypeError] if csts was not a Taipo::TypeElement::Constraints @raise [Taipo::SyntaxError] if there are constraints with the same name

@since 1.0.0 @api private

# File lib/taipo/type_element.rb, line 97
def constraints=(csts)
  msg = 'Argument csts was not a Taipo::TypeElement::Constraints.'
  raise ::TypeError, msg unless csts.is_a? Taipo::TypeElement::Constraints

  names = Hash.new
  csts.each do |c|
    msg = 'Contraints must have unique names.'
    raise Taipo::SyntaxError, msg if names.key?(c.name)
    if c.name == Taipo::TypeElement::Constraint::METHOD
      names['#' + c.value] = true
    else
      names[c.name] = true
    end
  end
  @constraints = csts
end
match?(arg) click to toggle source

Check if the argument matches the element

@param arg [Object] the argument to compare

@return [Boolean] the result

@raise [Taipo::SyntaxError] if the element's name is not defined (see

{#match_class?})

@since 1.0.0 @api private

# File lib/taipo/type_element.rb, line 125
def match?(arg)
  return true if optional? && arg.nil?

  match_class?(arg) && match_constraints?(arg) && match_children?(arg)
end
match_children?(arg) click to toggle source

Check if the class of the argument's children match

@param arg [Object] the argument to compare

@return [Boolean] the result

@since 1.4.0 @api private

# File lib/taipo/type_element.rb, line 160
def match_children?(arg)
  self_childless = @children.nil?
  arg_childless = !arg.is_a?(Enumerable) || arg.count == 0
  return true if self_childless
  return false if !self_childless && arg_childless

  arg.all? do |a|
    if !arg.is_a?(Array) && a.is_a?(Array)
      a.each.with_index.reduce(nil) do |memo,(component,index)|
        result = @children[index].any? { |c| c.match? component }
        (memo.nil?) ? result : memo && result
      end
    else # The elements of this collection have no components
      @children.first.any? { |c| c.match? a }
    end
  end
end
match_class?(arg) click to toggle source

Check if the class of the argument itself matches this element

@param arg [Object] the argument to compare

@return [Boolean] the result

@raise [Taipo::SyntaxError] if the element's name is not defined

@since 1.0.0 @api private

# File lib/taipo/type_element.rb, line 141
def match_class?(arg)
  actual_name = (optional?) ? @name[0..-2] : @name
  if actual_name == 'Boolean'
    arg.is_a?(TrueClass) || arg.is_a?(FalseClass)
  else
    msg = "Class to match #{actual_name} is not defined"
    raise Taipo::SyntaxError, msg unless Object.const_defined?(actual_name)
    arg.is_a? Object.const_get(actual_name)
  end
end
match_constraints?(arg) click to toggle source

Check if the argument fits within the constraints

@param arg [Object] the argument to compare

@return [Boolean] the result

@since 1.0.0 @api private

# File lib/taipo/type_element.rb, line 186
def match_constraints?(arg)
  return true if @constraints.nil?

  @constraints.all? { |c| c.constrain?(arg) }
end
optional?() click to toggle source

Check whether this element is an optional

An optional type is a variation on a normal type that also matches nil. Taipo borrows the syntax used in some other languages of denoting optional types by appending a question mark to the end of the class name.

@note This merely checks whether {Taipo::TypeElement#name} ends in a

question mark.

@return [Boolean] the result

@since 1.3.0 @api private

# File lib/taipo/type_element.rb, line 205
def optional?
  @name[-1] == '?'
end
to_s() click to toggle source

Return the String representation of this TypeElement

@return [String] the representation as a String

@since 1.1.0 @api private

# File lib/taipo/type_element.rb, line 215
def to_s
  name_str = @name
  children_str = (@children.nil?) ? '' : @children.to_s
  constraints_str = (@constraints.nil?) ? '' : @constraints.to_s
  name_str + children_str + constraints_str
end