Class: OptParseValidator::OptMultiChoices

Inherits:
OptArray show all
Defined in:
lib/opt_parse_validator/opts/multi_choices.rb

Overview

Implementation of the MultiChoices Option

Instance Attribute Summary

Attributes inherited from OptBase

#attrs, #option, #required

Instance Method Summary collapse

Methods inherited from OptArray

#separator

Methods inherited from OptBase

#advanced?, #alias?, #choices, #default, #help_messages, #required?, #required_unless, #to_long, #to_s, #to_sym, #value_if_empty

Constructor Details

#initialize(option, attrs = {}) ⇒ OptMultiChoices

Returns a new instance of OptMultiChoices.

Parameters:

  • option (Array)

    See OptBase#new

  • attrs (Hash) (defaults to: {})

Options Hash (attrs):

  • :choices (Hash)
  • :incompatible (Array<Array>)

Raises:



11
12
13
14
15
16
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 11

def initialize(option, attrs = {})
  raise Error, 'The :choices attribute is mandatory' unless attrs.key?(:choices)
  raise Error, 'The :choices attribute must be a hash' unless attrs[:choices].is_a?(Hash)

  super(option, attrs)
end

Instance Method Details

#append_choices_help_messagesObject



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 28

def append_choices_help_messages
  max_spaces = choices.keys.max_by(&:size).size

  choices.each do |key, opt|
    first_line_prefix  = " #{key} #{' ' * (max_spaces - key.length)}"
    other_lines_prefix = ' ' * first_line_prefix.size

    opt_help_messages(opt).each_with_index do |message, index|
      option << "#{index.zero? ? first_line_prefix : other_lines_prefix} #{message}"
    end
  end
end

#append_help_messagesObject



18
19
20
21
22
23
24
25
26
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 18

def append_help_messages
  option << 'Available Choices:'

  append_choices_help_messages

  super

  append_incompatible_help_messages
end

#append_incompatible_help_messagesObject



63
64
65
66
67
68
69
70
71
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 63

def append_incompatible_help_messages
  return if incompatible.empty?

  option << 'Incompatible choices (only one of each group/s can be used):'

  incompatible.each do |a|
    option << " - #{a.map(&:to_s).join(', ')}"
  end
end

#help_message_for_defaultObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 41

def help_message_for_default
  msg = +''

  default.each do |key, value|
    msg << if value == true
             key.to_s.titleize
           else
             "#{key.to_s.titleize}: #{value}"
           end
    msg << ', '
  end

  msg.chomp(', ')
end

#incompatibleArray<Array<Symbol>>

Returns:

  • (Array<Array<Symbol>>)


106
107
108
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 106

def incompatible
  Array(attrs[:incompatible])
end

#normalize(value) ⇒ Object

No normalization



131
132
133
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 131

def normalize(value)
  value
end

#opt_help_messages(opt) ⇒ Array<String>

Parameters:

Returns:

  • (Array<String>)


59
60
61
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 59

def opt_help_messages(opt)
  opt.help_messages.empty? ? [opt.to_s.humanize] : opt.help_messages
end

#validate(value) ⇒ Hash

Parameters:

  • value (String)

Returns:

  • (Hash)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 76

def validate(value)
  results = {}

  super(value).each do |item|
    opt = choices[item.to_sym]

    if opt
      opt_value = opt.value_if_empty.nil? ? true : opt.value_if_empty
    else
      opt, opt_value = value_from_pattern(item)
    end

    results[opt.to_sym] = opt.normalize(opt.validate(opt_value))
  end

  verify_compatibility(results)
end

#value_from_pattern(item) ⇒ Array

Returns:

  • (Array)

Raises:



95
96
97
98
99
100
101
102
103
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 95

def value_from_pattern(item)
  choices.each do |key, opt|
    next unless item =~ /\A#{key}(.*)\z/

    return [opt, Regexp.last_match[1]]
  end

  raise Error, "Unknown choice: #{item}"
end

#verify_compatibility(values) ⇒ Hash

Parameters:

  • values (Hash)

Returns:

  • (Hash)


113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/opt_parse_validator/opts/multi_choices.rb', line 113

def verify_compatibility(values)
  incompatible.each do |a|
    last_match = ''

    a.each do |key|
      sym = choices[key].to_sym

      next unless values.key?(sym)

      raise Error, "Incompatible choices detected: #{last_match}, #{key}" unless last_match.empty?

      last_match = key
    end
  end
  values
end