tty-prompt 0.18.1 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +95 -0
  3. data/README.md +598 -256
  4. data/lib/tty-prompt.rb +1 -2
  5. data/lib/tty/prompt.rb +192 -144
  6. data/lib/tty/prompt/answers_collector.rb +5 -5
  7. data/lib/tty/prompt/{enum_paginator.rb → block_paginator.rb} +20 -19
  8. data/lib/tty/prompt/choice.rb +9 -10
  9. data/lib/tty/prompt/choices.rb +30 -12
  10. data/lib/tty/prompt/confirm_question.rb +42 -16
  11. data/lib/tty/prompt/const.rb +17 -0
  12. data/lib/tty/prompt/converter_dsl.rb +6 -7
  13. data/lib/tty/prompt/converter_registry.rb +31 -26
  14. data/lib/tty/prompt/converters.rb +139 -32
  15. data/lib/tty/prompt/enum_list.rb +81 -26
  16. data/lib/tty/prompt/errors.rb +31 -0
  17. data/lib/tty/prompt/evaluator.rb +2 -2
  18. data/lib/tty/prompt/expander.rb +45 -15
  19. data/lib/tty/prompt/keypress.rb +33 -36
  20. data/lib/tty/prompt/list.rb +198 -63
  21. data/lib/tty/prompt/mask_question.rb +11 -8
  22. data/lib/tty/prompt/multi_list.rb +131 -28
  23. data/lib/tty/prompt/multiline.rb +9 -7
  24. data/lib/tty/prompt/paginator.rb +38 -26
  25. data/lib/tty/prompt/question.rb +92 -37
  26. data/lib/tty/prompt/question/checks.rb +20 -2
  27. data/lib/tty/prompt/question/modifier.rb +4 -2
  28. data/lib/tty/prompt/question/validation.rb +3 -3
  29. data/lib/tty/prompt/selected_choices.rb +77 -0
  30. data/lib/tty/prompt/slider.rb +125 -30
  31. data/lib/tty/prompt/statement.rb +3 -3
  32. data/lib/tty/prompt/suggestion.rb +7 -6
  33. data/lib/tty/prompt/symbols.rb +58 -34
  34. data/lib/tty/prompt/test.rb +36 -0
  35. data/lib/tty/prompt/timer.rb +75 -0
  36. data/lib/tty/prompt/utils.rb +1 -3
  37. data/lib/tty/prompt/version.rb +1 -1
  38. metadata +29 -227
  39. data/Rakefile +0 -8
  40. data/examples/ask.rb +0 -7
  41. data/examples/ask_valid.rb +0 -12
  42. data/examples/collect.rb +0 -21
  43. data/examples/echo.rb +0 -11
  44. data/examples/enum_select.rb +0 -7
  45. data/examples/enum_select_disabled.rb +0 -16
  46. data/examples/enum_select_paged.rb +0 -9
  47. data/examples/enum_select_wrapped.rb +0 -15
  48. data/examples/expand.rb +0 -29
  49. data/examples/in.rb +0 -9
  50. data/examples/inputs.rb +0 -10
  51. data/examples/key_events.rb +0 -15
  52. data/examples/keypress.rb +0 -9
  53. data/examples/mask.rb +0 -13
  54. data/examples/multi_select.rb +0 -8
  55. data/examples/multi_select_disabled.rb +0 -17
  56. data/examples/multi_select_paged.rb +0 -9
  57. data/examples/multi_select_wrapped.rb +0 -15
  58. data/examples/multiline.rb +0 -9
  59. data/examples/pause.rb +0 -9
  60. data/examples/select.rb +0 -24
  61. data/examples/select_disabled.rb +0 -18
  62. data/examples/select_enum.rb +0 -8
  63. data/examples/select_filtered.rb +0 -11
  64. data/examples/select_paginated.rb +0 -11
  65. data/examples/select_wrapped.rb +0 -15
  66. data/examples/slider.rb +0 -6
  67. data/examples/validation.rb +0 -9
  68. data/examples/yes_no.rb +0 -7
  69. data/lib/tty/prompt/messages.rb +0 -49
  70. data/lib/tty/prompt/timeout.rb +0 -78
  71. data/lib/tty/test_prompt.rb +0 -20
  72. data/spec/spec_helper.rb +0 -45
  73. data/spec/unit/ask_spec.rb +0 -132
  74. data/spec/unit/choice/eql_spec.rb +0 -22
  75. data/spec/unit/choice/from_spec.rb +0 -96
  76. data/spec/unit/choices/add_spec.rb +0 -12
  77. data/spec/unit/choices/each_spec.rb +0 -13
  78. data/spec/unit/choices/find_by_spec.rb +0 -10
  79. data/spec/unit/choices/new_spec.rb +0 -10
  80. data/spec/unit/choices/pluck_spec.rb +0 -9
  81. data/spec/unit/collect_spec.rb +0 -96
  82. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  83. data/spec/unit/converters/convert_char_spec.rb +0 -11
  84. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  85. data/spec/unit/converters/convert_date_spec.rb +0 -34
  86. data/spec/unit/converters/convert_file_spec.rb +0 -18
  87. data/spec/unit/converters/convert_number_spec.rb +0 -39
  88. data/spec/unit/converters/convert_path_spec.rb +0 -15
  89. data/spec/unit/converters/convert_range_spec.rb +0 -22
  90. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  91. data/spec/unit/converters/convert_string_spec.rb +0 -21
  92. data/spec/unit/converters/on_error_spec.rb +0 -9
  93. data/spec/unit/distance/distance_spec.rb +0 -73
  94. data/spec/unit/enum_paginator_spec.rb +0 -75
  95. data/spec/unit/enum_select_spec.rb +0 -446
  96. data/spec/unit/error_spec.rb +0 -20
  97. data/spec/unit/evaluator_spec.rb +0 -67
  98. data/spec/unit/expand_spec.rb +0 -198
  99. data/spec/unit/keypress_spec.rb +0 -72
  100. data/spec/unit/mask_spec.rb +0 -132
  101. data/spec/unit/multi_select_spec.rb +0 -511
  102. data/spec/unit/multiline_spec.rb +0 -77
  103. data/spec/unit/new_spec.rb +0 -20
  104. data/spec/unit/ok_spec.rb +0 -10
  105. data/spec/unit/paginator_spec.rb +0 -73
  106. data/spec/unit/question/checks_spec.rb +0 -97
  107. data/spec/unit/question/default_spec.rb +0 -31
  108. data/spec/unit/question/echo_spec.rb +0 -38
  109. data/spec/unit/question/in_spec.rb +0 -115
  110. data/spec/unit/question/initialize_spec.rb +0 -12
  111. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  112. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  113. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  114. data/spec/unit/question/modify_spec.rb +0 -41
  115. data/spec/unit/question/required_spec.rb +0 -92
  116. data/spec/unit/question/validate_spec.rb +0 -115
  117. data/spec/unit/question/validation/call_spec.rb +0 -31
  118. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  119. data/spec/unit/result_spec.rb +0 -40
  120. data/spec/unit/say_spec.rb +0 -67
  121. data/spec/unit/select_spec.rb +0 -660
  122. data/spec/unit/slider_spec.rb +0 -100
  123. data/spec/unit/statement/initialize_spec.rb +0 -15
  124. data/spec/unit/subscribe_spec.rb +0 -22
  125. data/spec/unit/suggest_spec.rb +0 -28
  126. data/spec/unit/warn_spec.rb +0 -21
  127. data/spec/unit/yes_no_spec.rb +0 -251
  128. data/tasks/console.rake +0 -11
  129. data/tasks/coverage.rake +0 -11
  130. data/tasks/spec.rake +0 -29
  131. data/tty-prompt.gemspec +0 -33
@@ -1,74 +1,181 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
- require 'necromancer'
5
-
6
- require_relative 'converter_dsl'
3
+ require_relative "const"
4
+ require_relative "converter_dsl"
7
5
 
8
6
  module TTY
9
7
  class Prompt
10
8
  module Converters
11
9
  extend ConverterDSL
12
10
 
13
- # Delegate Necromancer errors
14
- #
15
- # @api private
16
- def self.on_error
17
- if block_given?
18
- yield
19
- else
20
- raise ArgumentError, 'You need to provide a block argument.'
11
+ TRUE_VALUES = /^(t(rue)?|y(es)?|on|1)$/i.freeze
12
+ FALSE_VALUES = /^(f(alse)?|n(o)?|off|0)$/i.freeze
13
+
14
+ SINGLE_DIGIT_MATCHER = /^(?<digit>\-?\d+(\.\d+)?)$/.freeze
15
+ DIGIT_MATCHER = /^(?<open>-?\d+(\.\d+)?)
16
+ \s*(?<sep>(\.\s*){2,3}|-|,)\s*
17
+ (?<close>-?\d+(\.\d+)?)$
18
+ /x.freeze
19
+ LETTER_MATCHER = /^(?<open>\w)
20
+ \s*(?<sep>(\.\s*){2,3}|-|,)\s*
21
+ (?<close>\w)$
22
+ /x.freeze
23
+
24
+ converter(:boolean, :bool) do |input|
25
+ case input.to_s
26
+ when TRUE_VALUES then true
27
+ when FALSE_VALUES then false
28
+ else Const::Undefined
21
29
  end
22
- rescue Necromancer::ConversionTypeError => e
23
- raise ConversionError, e.message
24
- end
25
-
26
- converter(:bool) do |input|
27
- on_error { Necromancer.convert(input).to(:boolean, strict: true) }
28
30
  end
29
31
 
30
- converter(:string) do |input|
32
+ converter(:string, :str) do |input|
31
33
  String(input).chomp
32
34
  end
33
35
 
34
- converter(:symbol) do |input|
36
+ converter(:symbol, :sym) do |input|
35
37
  input.to_sym
36
38
  end
37
39
 
40
+ converter(:char) do |input|
41
+ String(input).chars.to_a[0]
42
+ end
43
+
38
44
  converter(:date) do |input|
39
- on_error { Necromancer.convert(input).to(:date, strict: true) }
45
+ begin
46
+ require "date" unless defined?(::Date)
47
+ ::Date.parse(input)
48
+ rescue ArgumentError
49
+ Const::Undefined
50
+ end
40
51
  end
41
52
 
42
53
  converter(:datetime) do |input|
43
- on_error { Necromancer.convert(input).to(:datetime, strict: true) }
54
+ begin
55
+ require "date" unless defined?(::Date)
56
+ ::DateTime.parse(input.to_s)
57
+ rescue ArgumentError
58
+ Const::Undefined
59
+ end
44
60
  end
45
61
 
46
- converter(:int) do |input|
47
- on_error { Necromancer.convert(input).to(:integer, strict: true) }
62
+ converter(:time) do |input|
63
+ begin
64
+ require "time"
65
+ ::Time.parse(input.to_s)
66
+ rescue ArgumentError
67
+ Const::Undefined
68
+ end
69
+ end
70
+
71
+ converter(:integer, :int) do |input|
72
+ begin
73
+ Integer(input)
74
+ rescue ArgumentError
75
+ Const::Undefined
76
+ end
48
77
  end
49
78
 
50
79
  converter(:float) do |input|
51
- on_error { Necromancer.convert(input).to(:float, strict: true) }
80
+ begin
81
+ Float(input)
82
+ rescue TypeError, ArgumentError
83
+ Const::Undefined
84
+ end
52
85
  end
53
86
 
87
+ # Convert string number to integer or float
88
+ #
89
+ # @return [Integer,Float,Const::Undefined]
90
+ #
91
+ # @api private
92
+ def cast_to_num(num)
93
+ ([convert(:int, num), convert(:float, num)] - [Const::Undefined]).first ||
94
+ Const::Undefined
95
+ end
96
+ module_function :cast_to_num
97
+
54
98
  converter(:range) do |input|
55
- on_error { Necromancer.convert(input).to(:range, strict: true) }
99
+ if input.is_a?(::Range)
100
+ input
101
+ elsif match = input.to_s.match(SINGLE_DIGIT_MATCHER)
102
+ digit = cast_to_num(match[:digit])
103
+ ::Range.new(digit, digit)
104
+ elsif match = input.to_s.match(DIGIT_MATCHER)
105
+ open = cast_to_num(match[:open])
106
+ close = cast_to_num(match[:close])
107
+ ::Range.new(open, close, match[:sep].gsub(/\s*/, "") == "...")
108
+ elsif match = input.to_s.match(LETTER_MATCHER)
109
+ ::Range.new(match[:open], match[:close],
110
+ match[:sep].gsub(/\s*/, "") == "...")
111
+ else Const::Undefined
112
+ end
56
113
  end
57
114
 
58
115
  converter(:regexp) do |input|
59
116
  Regexp.new(input)
60
117
  end
61
118
 
62
- converter(:file) do |input|
63
- ::File.open(::File.join(Dir.pwd, input))
119
+ converter(:filepath, :file) do |input|
120
+ ::File.expand_path(input)
64
121
  end
65
122
 
66
- converter(:path) do |input|
67
- Pathname.new(::File.join(Dir.pwd, input))
123
+ converter(:pathname, :path) do |input|
124
+ require "pathname" unless defined?(::Pathname)
125
+ ::Pathname.new(input)
68
126
  end
69
127
 
70
- converter(:char) do |input|
71
- String(input).chars.to_a[0]
128
+ converter(:uri) do |input|
129
+ require "uri" unless defined?(::URI)
130
+ ::URI.parse(input)
131
+ end
132
+
133
+ converter(:list, :array) do |val|
134
+ (val.respond_to?(:to_a) ? val : val.split(/(?<!\\),/))
135
+ .map { |v| v.strip.gsub(/\\,/, ",") }
136
+ .reject(&:empty?)
137
+ end
138
+
139
+ converter(:hash, :map) do |val|
140
+ values = val.respond_to?(:to_a) ? val : val.split(/[& ]/)
141
+ values.each_with_object({}) do |pair, pairs|
142
+ key, value = pair.split(/[=:]/, 2)
143
+ if (current = pairs[key.to_sym])
144
+ pairs[key.to_sym] = Array(current) << value
145
+ else
146
+ pairs[key.to_sym] = value
147
+ end
148
+ pairs
149
+ end
150
+ end
151
+
152
+ converter_registry.keys.each do |type|
153
+ next if type =~ /list|array|map|hash/
154
+
155
+ [:"#{type}_list", :"#{type}_array", :"#{type}s"].each do |new_type|
156
+ converter(new_type) do |val|
157
+ converter_registry[:array].(val).map do |obj|
158
+ converter_registry[type].(obj)
159
+ end
160
+ end
161
+ end
162
+
163
+ [:"#{type}_map", :"#{type}_hash"].each do |new_type|
164
+ converter(new_type) do |val|
165
+ converter_registry[:hash].(val).each_with_object({}) do |(k, v), h|
166
+ h[k] = converter_registry[type].(v)
167
+ end
168
+ end
169
+ end
170
+
171
+ [:"string_#{type}_map", :"str_#{type}_map",
172
+ :"string_#{type}_hash", :"str_#{type}_hash"].each do |new_type|
173
+ converter(new_type) do |val|
174
+ converter_registry[:hash].(val).each_with_object({}) do |(k, v), h|
175
+ h[converter_registry[:string].(k)] = converter_registry[type].(v)
176
+ end
177
+ end
178
+ end
72
179
  end
73
180
  end # Converters
74
181
  end # Prompt
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'English'
3
+ require "English"
4
4
 
5
- require_relative 'choices'
6
- require_relative 'enum_paginator'
7
- require_relative 'paginator'
8
- require_relative 'symbols'
5
+ require_relative "choices"
6
+ require_relative "block_paginator"
7
+ require_relative "paginator"
9
8
 
10
9
  module TTY
11
10
  class Prompt
@@ -14,22 +13,25 @@ module TTY
14
13
  #
15
14
  # @api private
16
15
  class EnumList
17
- include Symbols
16
+ PAGE_HELP = "(Press tab/right or left to reveal more choices)"
18
17
 
19
- PAGE_HELP = '(Press tab/right or left to reveal more choices)'
18
+ # Checks type of default parameter to be integer
19
+ INTEGER_MATCHER = /\A[-+]?\d+\Z/.freeze
20
20
 
21
21
  # Create instance of EnumList menu.
22
22
  #
23
23
  # @api public
24
- def initialize(prompt, options = {})
24
+ def initialize(prompt, **options)
25
25
  @prompt = prompt
26
26
  @prefix = options.fetch(:prefix) { @prompt.prefix }
27
- @enum = options.fetch(:enum) { ')' }
28
- @default = options.fetch(:default) { 1 }
27
+ @enum = options.fetch(:enum) { ")" }
28
+ @default = options.fetch(:default, nil)
29
29
  @active_color = options.fetch(:active_color) { @prompt.active_color }
30
30
  @help_color = options.fetch(:help_color) { @prompt.help_color }
31
31
  @error_color = options.fetch(:error_color) { @prompt.error_color }
32
- @cycle = options.fetch(:cycle) { false }
32
+ @cycle = options.fetch(:cycle, false)
33
+ @quiet = options.fetch(:quiet) { @prompt.quiet }
34
+ @symbols = @prompt.symbols.merge(options.fetch(:symbols, {}))
33
35
  @input = nil
34
36
  @done = false
35
37
  @first_render = true
@@ -38,10 +40,22 @@ module TTY
38
40
  @choices = Choices.new
39
41
  @per_page = options[:per_page]
40
42
  @page_help = options[:page_help] || PAGE_HELP
41
- @paginator = EnumPaginator.new
43
+ @paginator = BlockPaginator.new
42
44
  @page_active = @default
43
45
  end
44
46
 
47
+ # Change symbols used by this prompt
48
+ #
49
+ # @param [Hash] new_symbols
50
+ # the new symbols to use
51
+ #
52
+ # @api public
53
+ def symbols(new_symbols = (not_set = true))
54
+ return @symbols if not_set
55
+
56
+ @symbols.merge!(new_symbols)
57
+ end
58
+
45
59
  # Set default option selected
46
60
  #
47
61
  # @api public
@@ -49,6 +63,15 @@ module TTY
49
63
  @default = default
50
64
  end
51
65
 
66
+ # Check if default value is set
67
+ #
68
+ # @return [Boolean]
69
+ #
70
+ # @api public
71
+ def default?
72
+ !@default.to_s.empty?
73
+ end
74
+
52
75
  # Set number of items per page
53
76
  #
54
77
  # @api public
@@ -83,6 +106,13 @@ module TTY
83
106
  @enum = value
84
107
  end
85
108
 
109
+ # Set quiet mode
110
+ #
111
+ # @api public
112
+ def quiet(value)
113
+ @quiet = value
114
+ end
115
+
86
116
  # Add a single choice
87
117
  #
88
118
  # @api public
@@ -125,8 +155,9 @@ module TTY
125
155
  end
126
156
 
127
157
  def keypress(event)
128
- if [:backspace, :delete].include?(event.key.name)
158
+ if %i[backspace delete].include?(event.key.name)
129
159
  return if @input.empty?
160
+
130
161
  @input.chop!
131
162
  mark_choice_as_active
132
163
  elsif event.value =~ /^\d+$/
@@ -144,7 +175,7 @@ module TTY
144
175
  if choice_in_range && !choice_disabled || @input.empty?
145
176
  @done = true
146
177
  else
147
- @input = ''
178
+ @input = ""
148
179
  @failure = true
149
180
  end
150
181
  end
@@ -193,6 +224,8 @@ module TTY
193
224
  def validate_defaults
194
225
  msg = if @default.nil? || @default.to_s.empty?
195
226
  "default index must be an integer in range (1 - #{choices.size})"
227
+ elsif @default.to_s !~ INTEGER_MATCHER
228
+ validate_default_name
196
229
  elsif @default < 1 || @default > @choices.size
197
230
  "default index #{@default} out of range (1 - #{@choices.size})"
198
231
  elsif choices[@default - 1] && choices[@default - 1].disabled?
@@ -202,11 +235,31 @@ module TTY
202
235
  raise(ConfigurationError, msg) if msg
203
236
  end
204
237
 
238
+ # Validate default choice name
239
+ #
240
+ # @return [String]
241
+ #
242
+ # @api private
243
+ def validate_default_name
244
+ default_choice = choices.find_by(:name, @default.to_s)
245
+ if default_choice.nil?
246
+ "no choice found for the default name: #{@default.inspect}"
247
+ elsif default_choice.disabled?
248
+ "default name #{@default.inspect} matches disabled choice"
249
+ end
250
+ end
251
+
205
252
  # Setup default option and active selection
206
253
  #
207
254
  # @api private
208
255
  def setup_defaults
256
+ if @default.to_s.empty?
257
+ @default = (0..choices.length).find { |i| !choices[i].disabled? } + 1
258
+ end
209
259
  validate_defaults
260
+ if default_choice = choices.find_by(:name, @default)
261
+ @default = choices.index(default_choice) + 1
262
+ end
210
263
  mark_choice_as_active
211
264
  end
212
265
 
@@ -219,7 +272,7 @@ module TTY
219
272
  #
220
273
  # @api private
221
274
  def render
222
- @input = ''
275
+ @input = ""
223
276
  until @done
224
277
  question = render_question
225
278
  @prompt.print(question)
@@ -231,7 +284,7 @@ module TTY
231
284
  question_lines = question.split($INPUT_RECORD_SEPARATOR, -1)
232
285
  @prompt.print(refresh(question_lines_count(question_lines)))
233
286
  end
234
- @prompt.print(render_question)
287
+ @prompt.print(render_question) unless @quiet
235
288
  answer
236
289
  end
237
290
 
@@ -286,8 +339,8 @@ module TTY
286
339
  #
287
340
  # @api private
288
341
  def error_message
289
- error = 'Please enter a valid number'
290
- "\n" + @prompt.decorate('>>', @error_color) + ' ' + error
342
+ error = "Please enter a valid number"
343
+ "\n" + @prompt.decorate(">>", @error_color) + " " + error
291
344
  end
292
345
 
293
346
  # Render error message and return cursor to position of input
@@ -310,8 +363,9 @@ module TTY
310
363
  #
311
364
  # @api private
312
365
  def render_header
313
- return '' unless @done
314
- return '' unless @active
366
+ return "" unless @done
367
+ return "" unless @active
368
+
315
369
  selected_item = @choices[@active - 1].name.to_s
316
370
  @prompt.decorate(selected_item, @active_color)
317
371
  end
@@ -331,7 +385,8 @@ module TTY
331
385
  #
332
386
  # @api private
333
387
  def page_help_message
334
- return '' unless paginated?
388
+ return "" unless paginated?
389
+
335
390
  "\n" + @prompt.decorate(@page_help, @help_color)
336
391
  end
337
392
 
@@ -358,15 +413,15 @@ module TTY
358
413
  output = []
359
414
 
360
415
  @paginator.paginate(@choices, @page_active, @per_page) do |choice, index|
361
- num = (index + 1).to_s + @enum + ' '
416
+ num = (index + 1).to_s + @enum + " "
362
417
  selected = num.to_s + choice.name.to_s
363
418
  output << if index + 1 == @active && !choice.disabled?
364
- (' ' * 2) + @prompt.decorate(selected, @active_color)
419
+ (" " * 2) + @prompt.decorate(selected, @active_color)
365
420
  elsif choice.disabled?
366
- @prompt.decorate(symbols[:cross], :red) + ' ' +
367
- selected + ' ' + choice.disabled.to_s
421
+ @prompt.decorate(@symbols[:cross], :red) + " " +
422
+ selected + " " + choice.disabled.to_s
368
423
  else
369
- (' ' * 2) + selected
424
+ (" " * 2) + selected
370
425
  end
371
426
  output << "\n"
372
427
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Prompt
5
+ Error = Class.new(StandardError)
6
+
7
+ # Raised when wrong parameter is used to configure prompt
8
+ ConfigurationError = Class.new(Error)
9
+
10
+ # Raised when type conversion cannot be performed
11
+ ConversionError = Class.new(Error)
12
+
13
+ # Raised when the passed in validation argument is of wrong type
14
+ ValidationCoercion = Class.new(Error)
15
+
16
+ # Raised when the required argument is not supplied
17
+ ArgumentRequired = Class.new(Error)
18
+
19
+ # Raised when the argument validation fails
20
+ ArgumentValidation = Class.new(Error)
21
+
22
+ # Raised when the argument is not expected
23
+ InvalidArgument = Class.new(Error)
24
+
25
+ # Raised when overriding already defined conversion
26
+ ConversionAlreadyDefined = Class.new(Error)
27
+
28
+ # Raised when conversion type isn't registered
29
+ UnsupportedConversion = Class.new(Error)
30
+ end # Prompt
31
+ end # TTY