lib/tty/prompt/question.rb in tty-prompt-0.1.0 vs lib/tty/prompt/question.rb in tty-prompt-0.2.0
- old
+ new
@@ -1,183 +1,135 @@
# encoding: utf-8
require 'tty/prompt/question/modifier'
require 'tty/prompt/question/validation'
-
require 'tty/prompt/response_delegation'
module TTY
# A class responsible for shell prompt interactions.
class Prompt
# A class representing a command line question
class Question
include ResponseDelegation
- PREFIX = ' + '
- MULTIPLE_PREFIX = ' * '
- ERROR_PREFIX = ' ERROR:'
+ # Store question message
+ # @api public
+ attr_reader :message
- # Store statement.
- #
- # @api private
- attr_accessor :statement
-
# Store default value.
#
# @api private
attr_reader :default_value
- attr_reader :required
- private :required
-
attr_reader :validation
# Controls character processing of the answer
#
# @api public
attr_reader :modifier
- # Returns valid answers
- #
- # @api public
- attr_reader :valid_values
-
attr_reader :error
# Returns character mode
#
# @api public
attr_reader :character
# @api private
- attr_reader :shell
- private :shell
+ attr_reader :prompt
# Initialize a Question
#
# @api public
- def initialize(shell, options = {})
- @shell = shell || Prompt.new
+ def initialize(prompt, options = {})
+ @prompt = prompt || Prompt.new
@required = options.fetch(:required) { false }
@echo = options.fetch(:echo) { true }
@raw = options.fetch(:raw) { false }
@mask = options.fetch(:mask) { false }
@character = options.fetch(:character) { false }
@in = options.fetch(:in) { false }
@modifier = Modifier.new options.fetch(:modifier) { [] }
- @valid_values = options.fetch(:valid) { [] }
- @validation = Validation.new options.fetch(:validation) { nil }
- @default_value = nil
+ @validation = Validation.new(options.fetch(:validation) { nil })
+ @default = options.fetch(:default) { nil }
@error = false
@converter = Necromancer.new
+ @read = options.fetch(:read) { nil }
end
- # Set a new prompt
+ # Call the quesiton
#
# @param [String] message
#
# @return [self]
#
# @api public
- def prompt(message)
- self.statement = message
- shell.say shell.prefix + statement
- self
+ def call(message, &block)
+ @message = message
+ block.call(self) if block
+ prompt.output.print("#{prompt.prefix}#{message}")
+ render
end
+ # Reader answer and convert to type
+ #
+ # @api private
+ def render
+ dispatch.read_type(@read)
+ end
+
# Set default value.
#
# @api public
def default(value)
- return self if value == ''
- @default_value = value
- self
+ return @default unless value
+ @default = value
end
# Check if default value is set
#
# @return [Boolean]
#
# @api public
def default?
- !!@default_value
+ !!@default
end
- # Ensure that passed argument is present if required option
+ # Ensure that passed argument is present or not
#
- # @return [Question]
+ # @return [Boolean]
#
# @api public
- def argument(value)
- case value
- when :required
- @required = true
- when :optional
- @required = false
- end
- self
+ def required(value)
+ @required = value
end
- # Check if required argument present.
- #
- # @return [Boolean]
- #
- # @api private
- def required?
- required
- end
-
# Set validation rule for an argument
#
# @param [Object] value
#
# @return [Question]
#
# @api public
def validate(value = nil, &block)
@validation = Validation.new(value || block)
- self
end
- # Set expected values
- #
- # @param [Array] values
- #
- # @return [self]
- #
- # @api public
- def valid(values)
- @valid_values = values
- self
- end
-
- # Reset question object.
- #
- # @api public
- def clean
- @statement = nil
- @default_value = nil
- @required = false
- @modifier = nil
- end
-
# Modify string according to the rule given.
#
# @param [Symbol] rule
#
# @api public
def modify(*rules)
@modifier = Modifier.new(*rules)
- self
end
# Setup behaviour when error(s) occur
#
# @api public
def on_error(action = nil)
@error = action
- self
end
# Check if error behaviour is set
#
# @api public
@@ -190,11 +142,10 @@
#
# @api public
def echo(value = nil)
return @echo if value.nil?
@echo = value
- self
end
# Chec if echo is set
#
# @api public
@@ -206,11 +157,10 @@
#
# @api public
def raw(value = nil)
return @raw if value.nil?
@raw = value
- self
end
# Check if raw mode is set
#
# @api public
@@ -226,11 +176,10 @@
#
# @api public
def mask(char = nil)
return @mask if char.nil?
@mask = char
- self
end
# Check if character mask is set
#
# @return [Boolean]
@@ -248,11 +197,10 @@
#
# @api public
def char(value = nil)
return @character if value.nil?
@character = value
- self
end
# Check if character intput is set
#
# @return [Boolean]
@@ -268,11 +216,10 @@
#
# @api public
def in(value = nil)
return @in if value.nil?
@in = @converter.convert(value).to(:range, strict: true)
- self
end
# Check if range is set
#
# @return [Boolean]
@@ -287,51 +234,55 @@
# @param [Object] value
#
# @return [Object]
#
# @api private
- def evaluate_response(value)
- return default_value if !value && default?
- check_required(value)
- return if value.nil?
+ def evaluate_response(input)
+ return @default if !input && default?
+ check_required(input)
+ return if input.nil?
- check_valid(value) unless valid_values.empty?
- within?(value)
- validation.valid_value?(value)
- modifier.apply_to(value)
+ within?(input)
+ validation.(input)
+ modifier.apply_to(input)
end
+ # Reset question object.
+ #
+ # @api public
+ def clean
+ @message = nil
+ @default = nil
+ @required = false
+ @modifier = nil
+ end
+
+ def to_s
+ "#{message}"
+ end
+
+ def inspect
+ "#<Question @message=#{message}>"
+ end
+
private
# Check if value is present
#
# @api private
def check_required(value)
- if required? && !default? && value.nil?
+ if @required && !default? && value.nil?
fail ArgumentRequired, 'No value provided for required'
end
end
- # Check if value matches any of the expected values
- #
- # @api private
- def check_valid(value)
- if Array(value).all? { |val| valid_values.include? val }
- return value
- else
- fail InvalidArgument, "Valid values are: #{valid_values.join(', ')}"
- end
- end
-
# Check if value is within expected range
#
# @api private
def within?(value)
if in? && value
- if @in.include?(value)
- else
- fail InvalidArgument, "Value #{value} is not included in the range #{@in}"
- end
+ @in.include?(value) || fail(InvalidArgument,
+ "Value #{value} is not included in the range #{@in}")
end
end
end # Question
end # Prompt
end # TTY