class Taipo::TypeElement
An element representing a type (including children and constraints)
@since 1.0.0 @api private
Attributes
The children for this element
@since 1.4.0 @api private
The constraints for this element
@since 1.0.0 @api private
The name of the element
@since 1.0.0 @api private
Public Class Methods
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
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
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
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
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
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
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
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
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