lib/command_mapper/types/type.rb
module CommandMapper
module Types
#
# The base type for all command-line argument types.
#
# ## Custom Types
#
# Custom types can be defined by extending the {Type} class.
#
# class PortRange < CommandMapper::Types::Type
#
# def validate(value)
# case value
# when Integer
# true
# when Range
# if value.begin.kind_of?(Integer)
# true
# else
# [false, "port range can only contain Integers"]
# end
# else
# [false, "port range must be an Integer or a Range of Integers"]
# end
# end
#
# def format(value)
# case value
# when Integer
# "#{value}"
# when Range
# "#{value.begin}-#{value.end}"
# end
# end
#
# end
#
#
# The custom type can define the following methods:
#
# * `#initialize` - accepts additional configuration options.
# * `#validate` - accepts a value object and returns `true` (indicating the
# value is valid) or `[false, message]` (indicating the value is invalid).
# * `#format` - accepts a validated value and returns a formatted String.
#
# Once defined, custom {Type} classes can be used with `option` or
# `argument` and passed in via the `type:` keyword argument.
#
# option "--ports", value: {required: true, type: PortRange.new}
#
# argument :ports, required: true, type: PortRange.new
#
# @api semipublic
#
class Type
#
# The default `validate` method for all types.
#
# @param [Object] value
# The given value to validate.
#
# @return [true, (false, String)]
# Returns true if the value is valid, or `false` and a validation error
# message if the value is not compatible.
#
def validate(value)
true
end
#
# The default `format` method for all types.
#
# @param [#to_s] value
# The given value to format.
#
# @return [String]
# The String version of the value.
#
def format(value)
value.to_s
end
end
require 'command_mapper/types/str'
#
# Converts a value into a {Type} object.
#
# @param [Type, Hash, nil] value
# The type value or `Hash` of keyword arguments.
#
# @return [Type, Str]
# The type object or a new {Str} type object if a `Hash` of keyword
# arguments is given.
#
# @raise [ArgumentError]
# The given type value was not a {Type}, `Hash`, or `nil`,
#
# @api semipublic
#
def self.Type(value)
case value
when Type then value
when Hash then Str.new(**value)
when nil then nil
else
raise(ArgumentError,"value must be a #{Type}, Hash, or nil: #{value.inspect}")
end
end
end
end