module Stannum::Struct::ClassMethods

Class methods to extend the class when including Stannum::Struct.

Public Instance Methods

attribute(attr_name, attr_type, **options) click to toggle source

Defines an attribute on the struct.

When an attribute is defined, each of the following steps is executed:

  • Adds the attribute to ::Attributes and the .attributes class method.

  • Adds the attribute to attributes and the associated methods, such as assign_attributes, [] and []=.

  • Defines reader and writer methods.

  • Adds a type constraint to ::Attributes::Contract, and indirectly to ::Contract.

@param attr_name [String, Symbol] The name of the attribute. Must be a

non-empty String or Symbol.

@param attr_type [Class, String] The type of the attribute. Must be a

Class or Module, or the name of a class or module.

@param options [Hash] Additional options for the attribute.

@option options [Object] :default The default value for the attribute.

Defaults to nil.

@return [Symbol] The attribute name as a symbol.

# File lib/stannum/struct.rb, line 105
def attribute(attr_name, attr_type, **options)
  attribute  = attributes.define_attribute(
    name:    attr_name,
    type:    attr_type,
    options: options
  )
  constraint = Stannum::Constraints::Type.new(
    attribute.type,
    required: attribute.required?
  )

  self::Contract.add_constraint(
    constraint,
    property: attribute.reader_name
  )

  attr_name.intern
end
attributes() click to toggle source

@return [Stannum::Schema] The Schema object for the Struct.

# File lib/stannum/struct.rb, line 126
def attributes
  self::Attributes
end
constraint(attr_name = nil, constraint = nil, &block) click to toggle source

Defines a constraint on the struct or one of its properties.

@overload constraint()

Defines a constraint on the struct.

A new Stannum::Constraint instance will be generated, passing the
block from .constraint to the new constraint. This constraint will be
added to the contract.

@yieldparam struct [Stannum::Struct] The struct at the time the
  constraint is evaluated.

@overload constraint(constraint)

Defines a constraint on the struct.

The given constraint is added to the contract. When the contract is
evaluated, this constraint will be matched against the struct.

@param constraint [Stannum::Constraints::Base] The constraint to add.

@overload constraint(attr_name)

Defines a constraint on the given attribute or property.

A new Stannum::Constraint instance will be generated, passing the
block from .constraint to the new constraint. This constraint will be
added to the contract.

@param attr_name [String, Symbol] The name of the attribute or
  property to constrain.

@yieldparam value [Object] The value of the attribute or property of
  the struct at the time the constraint is evaluated.

@overload constraint(attr_name, constraint)

Defines a constraint on the given attribute or property.

The given constraint is added to the contract. When the contract is
evaluated, this constraint will be matched against the value of the
attribute or property.

@param attr_name [String, Symbol] The name of the attribute or
  property to constrain.
@param constraint [Stannum::Constraints::Base] The constraint to add.
# File lib/stannum/struct.rb, line 173
def constraint(attr_name = nil, constraint = nil, &block)
  attr_name, constraint = resolve_constraint(attr_name, constraint)

  if block_given?
    constraint = Stannum::Constraint.new(&block)
  else
    validate_constraint(constraint)
  end

  contract.add_constraint(constraint, property: attr_name)
end
contract() click to toggle source

@return [Stannum::Contract] The Contract object for the Struct.

# File lib/stannum/struct.rb, line 186
def contract
  self::Contract
end

Private Instance Methods

inherited(other) click to toggle source

@api private

Hook to execute when a struct class is subclassed.

Calls superclass method
# File lib/stannum/struct.rb, line 195
def inherited(other)
  super

  Struct.build(other) if other.is_a?(Class)
end
resolve_constraint(attr_name, constraint) click to toggle source
# File lib/stannum/struct.rb, line 201
def resolve_constraint(attr_name, constraint)
  return [nil, attr_name] if attr_name.is_a?(Stannum::Constraints::Base)

  validate_attribute_name(attr_name)

  [attr_name.nil? ? attr_name : attr_name.intern, constraint]
end
validate_attribute_name(name) click to toggle source
# File lib/stannum/struct.rb, line 209
def validate_attribute_name(name)
  return if name.nil?

  unless name.is_a?(String) || name.is_a?(Symbol)
    raise ArgumentError, 'attribute must be a String or Symbol'
  end

  raise ArgumentError, "attribute can't be blank" if name.empty?
end
validate_constraint(constraint) click to toggle source
# File lib/stannum/struct.rb, line 219
def validate_constraint(constraint)
  raise ArgumentError, "constraint can't be blank" if constraint.nil?

  return if constraint.is_a?(Stannum::Constraints::Base)

  raise ArgumentError, 'constraint must be a Stannum::Constraints::Base'
end