mp-utils 0.1.3 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e35a3d445a73ca931a0503b2d162c1a54a40b8b3bc04f4961884c607a6c6dfde
4
- data.tar.gz: 510838aa718f0475e7ad846b0913325b89a711050566ee2778a655e29ec2fdc4
3
+ metadata.gz: 53115e447f66c67ce9cf751d87416c01ee514aed742b3e24698374bed4faaa00
4
+ data.tar.gz: d365ed87408163c044f558367c2fd31c87a884d10e1e2576e394885be01ede84
5
5
  SHA512:
6
- metadata.gz: a3e48fb89f3505cc381529c052e26fbd61ed490674216fdd8ffe121f8849ce931e0432ac8d02b0ab88e3ce5353ab7424ff656069057575f64e3793636d3ba854
7
- data.tar.gz: de22e7695b09793b51aaa80205b036c4b2e2e7adba46a2c41c29543cfe6798795ffc8e93bbd037b43757472a294da817fe2c4b478e61d541333980623dc99452
6
+ metadata.gz: f4825498b3b32141ba3a92a72003a8395a8f9176d530b5c6d7b24251ef2d664a70190d8377cff4173dac88193bfd00e285a234ef251ba36df332199e1f409269
7
+ data.tar.gz: e885a6df65146092e1bb8c368d01d0f222fde669c1fe1bac532b5d6a1fdb81b40c3efda6f7eca67b927b374d793b75ae7908c4b51c938cbefa159ce6bddbae74
data/lib/mp_utils.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'utils/key'
4
+ require 'utils/array'
4
5
  require 'utils/message'
6
+ require 'utils/question'
5
7
  require 'resources/path_helper'
@@ -0,0 +1 @@
1
+ (Yes/No/Y/N)
@@ -0,0 +1,3 @@
1
+ You need to answer with "Yes or No" only.
2
+ These are the valid response options: Yes, No, Y, N
3
+ Note: You can use both lowercase and uppercase letters for the answers.
@@ -0,0 +1,2 @@
1
+ You need to provide a numeric value with decimal places.
2
+ Example: 3143.14
@@ -0,0 +1 @@
1
+ The index value needs to be within the above listing.
@@ -0,0 +1,2 @@
1
+ You need to provide an integer numeric value.
2
+ Example: 123456
@@ -0,0 +1,2 @@
1
+ Message does not meet the requested standard.
2
+ Please provide a message within the expected standard.
@@ -18,7 +18,7 @@ module Resources
18
18
  # {define} method. This method allows for easy retrieval of the custom path, facilitating flexible
19
19
  # resource management.
20
20
  #
21
- # @return [String, nil] the custom resources path as defined by the environment variable, or nil if it hasn't been set.
21
+ # @return [String, nil] the custom path as defined by the environment variable, or nil if it hasn't been set.
22
22
  def self.custom_path
23
23
  ENV['SCRIPT_CUSTOM_RESOURCES']
24
24
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Extension to Ruby's Array class to enhance functionality.
4
+ class Array
5
+ # Lists all elements in the array with their index.
6
+ #
7
+ # This method outputs each element of the array to the console, prefixed by its index (1-based).
8
+ # The index is right-justified based on the length of the array, ensuring a tidy, column-aligned output.
9
+ #
10
+ # Example output for a 3-element array:
11
+ # |1| Element 1
12
+ # |2| Element 2
13
+ # |3| Element 3
14
+ #
15
+ # @return [void]
16
+ def list_all_elements
17
+ index_size = count.to_s.length
18
+ each_index do |index|
19
+ puts "|#{(index + 1).to_s.rjust(index_size)}| #{self[index]}"
20
+ end
21
+ end
22
+ end
data/lib/utils/message.rb CHANGED
@@ -20,10 +20,11 @@ class Message
20
20
  # Initializes a new instance of the Message class with a given message template.
21
21
  #
22
22
  # @param message [String] The message template to be used.
23
- # @param replaces [String] The replaces Hash used to change key finded in @message by custom values.
23
+ # @param replaces [Hash] Used to replace all occurrences of a key with its value.
24
24
  def initialize(message, replaces: nil)
25
25
  raise 'Messsage replaces content need be a Hash' if !replaces.nil? && !replaces.is_a?(Hash)
26
- @replaces = replaces
26
+
27
+ @to_replace = replaces
27
28
  @message = message
28
29
  end
29
30
 
@@ -42,29 +43,8 @@ class Message
42
43
  #
43
44
  # @return [String] The formatted message with placeholders substituted with actual content.
44
45
  def to_s
45
- new_message = String.new(@message)
46
- keys = Key.find_keys_in(@message)
47
-
48
- if keys.count.positive?
49
- keys.each do |key|
50
- message = recover_message_with(key.value)
51
- new_message.gsub!(key.to_s, message) if message != key.value
52
- end
53
- else
54
- new_message = recover_message_with(new_message)
55
- end
56
-
57
- if !@replaces.nil?
58
- @replaces.each do |key, value|
59
- if key.is_a?(Key)
60
- new_message.gsub!(key.to_regexp, value.to_s)
61
- else
62
- new_message.gsub!(/#{Regexp.escape(key.to_s)}/, value.to_s)
63
- end
64
- end
65
- end
66
-
67
- new_message
46
+ new_message = replace_message_keys(String.new(@message))
47
+ replace_all_to_replace_elements(new_message)
68
48
  end
69
49
  end
70
50
 
@@ -90,6 +70,40 @@ class Message
90
70
  File.join(Resources.library_path, 'messages')
91
71
  end
92
72
 
73
+ # Replaces keys found in the original message with their corresponding values.
74
+ #
75
+ # @param message [String] The original message with keys to be replaced.
76
+ # @return [String] The message with keys replaced by their corresponding values.
77
+ def replace_message_keys(message)
78
+ keys = Key.find_keys_in(message)
79
+ return recover_message_with(message) if keys.empty?
80
+
81
+ keys.each do |key|
82
+ key_message = recover_message_with(key.value)
83
+ message.gsub!(key.to_s, key_message) if key_message != key.value
84
+ end
85
+
86
+ message
87
+ end
88
+
89
+ # Replaces all placeholders in the message with their corresponding values from the @to_replace hash.
90
+ #
91
+ # @param message [String] The message with placeholders to replace.
92
+ # @return [String] The message with all placeholders replaced with actual content.
93
+ def replace_all_to_replace_elements(message)
94
+ return message if @to_replace.nil?
95
+
96
+ @to_replace.each do |key, value|
97
+ if key.is_a?(Key)
98
+ message.gsub!(key.to_regexp, value.to_s)
99
+ else
100
+ message.gsub!(/#{Regexp.escape(key.to_s)}/, value.to_s)
101
+ end
102
+ end
103
+
104
+ message
105
+ end
106
+
93
107
  # Attempts to recover and return the content of a message file identified by the file_name parameter.
94
108
  # It first looks in the custom path (if defined) and then in the library path.
95
109
  #
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'message'
4
+ require_relative 'array'
5
+
6
+ # The Question class facilitates the creation and management of interactive questions in the console.
7
+ # It provides methods to validate and return user input as various data types including boolean,
8
+ # float, integer, options (from a list), and string.
9
+ class Question
10
+ # Initializes a new instance of the Question class.
11
+ #
12
+ # @param message [String] The question message to be displayed to the user.
13
+ def initialize(message)
14
+ @message = Message.new(message)
15
+ end
16
+
17
+ # Prompts the user with a boolean question and returns the answer as true or false.
18
+ #
19
+ # @param error_message [String, nil] Custom error message for invalid inputs.
20
+ # @return [Boolean] True if the user answers affirmatively, otherwise false.
21
+ def bool_answer(error_message: nil)
22
+ error = error_message || File.join('question', 'error', 'bool')
23
+ bool_sufix = Message.new(File.join('question', 'bool_sufix'))
24
+ result = read_input("#{@message} #{bool_sufix}", error_message: error) do |input|
25
+ input.match?(/^((Y|y)((E|e)(S|s))*)|((N|n)(O|o)*)$/)
26
+ end
27
+
28
+ result.match?(/^(Y|y)((E|e)(S|s))*$/)
29
+ end
30
+
31
+ # Prompts the user for a floating-point number and returns the value.
32
+ #
33
+ # @param error_message [String, nil] Custom error message for invalid inputs.
34
+ # @return [Float] The user's input converted to a float.
35
+ def float_answer(error_message: nil)
36
+ error = error_message || File.join('question', 'error', 'float')
37
+ string_answer(regex: /^\d+\.\d+$/, error_message: error).to_f
38
+ end
39
+
40
+ # Prompts the user for an integer and returns the value.
41
+ #
42
+ # @param error_message [String, nil] Custom error message for invalid inputs.
43
+ # @return [Integer] The user's input converted to an integer.
44
+ def integer_answer(error_message: nil)
45
+ error = error_message || File.join('question', 'error', 'integer')
46
+ string_answer(regex: /^\d+$/, error_message: error).to_i
47
+ end
48
+
49
+ # Prompts the user to select an option from a given list and returns the selected option.
50
+ #
51
+ # @param options [Array] The list of options for the user to choose from.
52
+ # @param error_message [String, nil] Custom error message for invalid inputs.
53
+ # @raise [RuntimeError] If options is not an Array or is empty.
54
+ # @return [Object] The selected option from the list. If options count is 1 return the first element.
55
+ def option_answer(options, error_message: nil)
56
+ raise 'Options should be an Array' unless options.is_a?(Array)
57
+ raise 'Options should not be empty' if options.empty?
58
+ return options.first if options.count == 1
59
+
60
+ options.list_all_elements
61
+ index = read_index_input(count: options.count, error_message: error_message)
62
+ options[index]
63
+ end
64
+
65
+ # Prompts the user for a string that matches a given regular expression.
66
+ #
67
+ # @param regex [Regexp, nil] The regular expression the user's input must match.
68
+ # @param error_message [String, nil] Custom error message for invalid inputs.
69
+ # @return [String] The user's input if it matches the given regex.
70
+ def string_answer(regex: nil, error_message: nil)
71
+ error = error_message || File.join('question', 'error', 'regex')
72
+ read_input(error_message: error) do |input|
73
+ regex.nil? || input.match?(regex)
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # Displays a message to the user and returns their input, if it satisfies the given condition.
80
+ #
81
+ # @param message [String] The message to display to the user.
82
+ # @param error_message [String] The error message to display for invalid inputs.
83
+ # @yieldparam input [String] The user's input to validate.
84
+ # @yieldreturn [Boolean] True if the input is valid, otherwise false.
85
+ # @return [String] The user's valid input.
86
+ def read_input(message = @message, error_message:)
87
+ loop do
88
+ puts message
89
+ input = $stdin.gets.chomp
90
+ return input if yield input
91
+
92
+ puts Message.new(error_message)
93
+ end
94
+ end
95
+
96
+ # Reads an index input from the user, ensuring it falls within a specified range.
97
+ #
98
+ # This method prompts the user to enter an index number. It validates the input to ensure
99
+ # it is an integer within the range of 0 to (count - 1). If the input is invalid, an error
100
+ # message is displayed, and the user is prompted again.
101
+ #
102
+ # @param count [Integer] The count of items, setting the upper limit of the valid index range.
103
+ # @param error_message [String, nil] Custom error message for invalid index inputs.
104
+ # Defaults to the path 'question/error/index' if nil.
105
+ # @return [Integer] The user's input adjusted to be zero-based (input - 1) and validated to be within the range.
106
+ def read_index_input(count:, error_message: nil)
107
+ loop do
108
+ index = integer_answer(error_message: error_message) - 1
109
+ return index if index >= 0 && index < count
110
+
111
+ error = error_message || File.join('question', 'error', 'index')
112
+ puts Message.new(error)
113
+ end
114
+ end
115
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mp-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcio F Paludo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-10 00:00:00.000000000 Z
11
+ date: 2024-02-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Helpers to facilitate scripts Writing.
@@ -21,9 +21,17 @@ extra_rdoc_files: []
21
21
  files:
22
22
  - lib/mp_utils.rb
23
23
  - lib/resources/messages/hellow_world.txt
24
+ - lib/resources/messages/question/bool_sufix.txt
25
+ - lib/resources/messages/question/error/bool.txt
26
+ - lib/resources/messages/question/error/float.txt
27
+ - lib/resources/messages/question/error/index.txt
28
+ - lib/resources/messages/question/error/integer.txt
29
+ - lib/resources/messages/question/error/regex.txt
24
30
  - lib/resources/path_helper.rb
31
+ - lib/utils/array.rb
25
32
  - lib/utils/key.rb
26
33
  - lib/utils/message.rb
34
+ - lib/utils/question.rb
27
35
  homepage: https://github.com/MarcioFPaludo/ruby-mp-utils
28
36
  licenses:
29
37
  - MIT