riker 0.1.0.pre3 → 0.1.0.pre5

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: b819ce3e2d6fb0f84fd16e4eb754802ca3c655810179225c9f4ba9cff3d8f068
4
- data.tar.gz: ab2a5b0a1e9f3beb29c1ba8437de4b50be42f395c79cc833985c7da082c572f4
3
+ metadata.gz: fd3f7e1ef08e3dd6db6362747a86a4adbff4acd42a90bd251bbde583c01d5eca
4
+ data.tar.gz: 57c823093ded9ae1ec66fa7dcb6741385fd450072aa59eac0cf962ed0e32b74e
5
5
  SHA512:
6
- metadata.gz: ae433f9f555ceee2b68121953086c7de1e340773ccd1dc802a254126a7bcee94f7f77d2f28427b29e89a6f2e738f9b7aeb5ec709951eb84c150de49bff58ef9c
7
- data.tar.gz: 65a9c8f2be649a18223f3f97caf10b628155f6e0ac54b7891aba504616084eaa6ef85f79f7ac96ff55d7d057d18070bc3a84e527a0ba4b0faac276c80509e74b
6
+ metadata.gz: 92ae6575db90c03567fac3aa2b31d7350c1f616c011dc77c4a17c1cbb4cabc7ab2d630ac7a2311a8f6e341e08ec9fc1c26f162db047034f5122407bf0455185c
7
+ data.tar.gz: 90d6f23aa9224096af1b06a7aaa53a2290e4f125076fedcc58a685829b05e75b68e3d46218842e7ea1d337db01583a149d4f4363a1f7271fec115cbf5ea79f65
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in riker.gemspec
6
6
  gemspec
7
7
 
8
+ gem 'pry', '~> 0.14'
8
9
  gem 'rake', '~> 13.0'
9
10
  gem 'rspec', '~> 3.0'
10
11
  gem 'rubocop'
data/Gemfile.lock CHANGED
@@ -1,17 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- riker (0.1.0.pre2)
4
+ riker (0.1.0.pre5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
+ coderay (1.1.3)
10
11
  diff-lcs (1.5.0)
11
12
  json (2.6.2)
13
+ method_source (1.0.0)
12
14
  parallel (1.22.1)
13
15
  parser (3.1.2.1)
14
16
  ast (~> 2.4.1)
17
+ pry (0.14.1)
18
+ coderay (~> 1.1)
19
+ method_source (~> 1.0)
15
20
  rainbow (3.1.1)
16
21
  rake (13.0.6)
17
22
  regexp_parser (2.5.0)
@@ -49,6 +54,7 @@ PLATFORMS
49
54
  x86_64-linux
50
55
 
51
56
  DEPENDENCIES
57
+ pry (~> 0.14)
52
58
  rake (~> 13.0)
53
59
  riker!
54
60
  rspec (~> 3.0)
data/README.md CHANGED
@@ -12,7 +12,7 @@ High-Performance, Dependency-Free Command Pattern For Ruby
12
12
  ### In your gemfile:
13
13
 
14
14
  ```ruby
15
- gem 'riker', '0.1.0.pre3'
15
+ gem 'riker', '0.1.0.pre5'
16
16
  ```
17
17
 
18
18
  ### In your code:
@@ -26,6 +26,11 @@ class SimpleGreeting
26
26
  param :punctuation, default: '.'
27
27
 
28
28
  execute do
29
+ if first_name == 'Voldemort'
30
+ errors.add(:first_name, 'He who shall not be named!')
31
+ return
32
+ end
33
+
29
34
  return "Hello #{first_name}#{punctuation}" if last_name.nil?
30
35
 
31
36
  "Hello #{first_name} #{last_name}#{punctuation}"
@@ -44,6 +49,24 @@ SimpleGreeting.run!(first_name: 'Will', last_name: 'Riker')
44
49
 
45
50
  SimpleGreeting.run!(first_name: 'Will', last_name: 'Riker', punctuation: '!')
46
51
  # => "Hello Will Riker!"
52
+
53
+ SimpleGreeting.run!(first_name: 'Voldemort')
54
+ # => Riker::Outcome::ExecutionError => e
55
+ # => e.errors.messages == ['He who shall not be named!']
56
+
57
+ outcome = SimpleGreeting.run(first_name: 'Will')
58
+ outcome.valid?
59
+ # => true
60
+ outcome.result
61
+ # => "Hello Will."
62
+
63
+ outcome = SimpleGreeting.run(first_name: 'Voldemort')
64
+ outcome.invalid?
65
+ # => true
66
+ outcome.result
67
+ # => nil
68
+ outcome.errors.messages
69
+ # => ['He who shall not be named!']
47
70
  ```
48
71
 
49
72
  ## Default Procs
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Fallible Methods
6
+ #
7
+ # Every command has fallible functionality. This is
8
+ # how you can convey something has gone wrong to the
9
+ # caller of your command.
10
+ #
11
+ module FallibleMethods
12
+ # @return [Riker::Outcome::Errors]
13
+ def errors
14
+ @errors ||= Riker::Outcome::Errors.new
15
+ end
16
+
17
+ # @return [Boolean]
18
+ def errored?
19
+ defined?(@errors) && @errors.any?
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Individual Function
6
+ #
7
+ # Repsonible for debugging and writing out functions
8
+ # for a command to provide the needed functionality
9
+ # that is setup for it.
10
+ #
11
+ class Function
12
+ # @param command [Riker::Command]
13
+ def initialize(command)
14
+ @command = command
15
+ end
16
+
17
+ # @return [Symbol]
18
+ def name
19
+ raise NotImplementedError
20
+ end
21
+
22
+ # @return [Riker::Command::FunctionDetails]
23
+ def details
24
+ raise NotImplementedError
25
+ end
26
+
27
+ private
28
+
29
+ # @return [Riker::Command]
30
+ attr_reader :command
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Function Detail Data
6
+ #
7
+ # Holds information needed to write a function to a class
8
+ # with `class_eval` on a class object.
9
+ #
10
+ class FunctionDetails
11
+ # @return [String]
12
+ attr_reader :code
13
+
14
+ # @return [String]
15
+ attr_reader :file
16
+
17
+ # @return [Integer]
18
+ attr_reader :line
19
+
20
+ def initialize(code, file, line)
21
+ @code = code
22
+ @file = file
23
+ @line = line
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'run_bang_function'
4
+ require_relative 'initialize_function'
5
+ require_relative 'run_function'
6
+
7
+ module Riker
8
+ class Command
9
+ # Function Writer
10
+ #
11
+ # This is responsible for creating the functions that
12
+ # are needed to create a command pattern class.
13
+ #
14
+ class FunctionWriter
15
+ DEFAULT_FUNCTIONS = [
16
+ RunBangFunction,
17
+ RunFunction,
18
+ InitializeFunction
19
+ ].freeze
20
+
21
+ INSTANCE_METHOD_MODULES = [
22
+ FallibleMethods
23
+ ].freeze
24
+
25
+ # @return [Riker::Command]
26
+ attr_reader :command
27
+
28
+ # @return [Array<Riker::Command::Function>]
29
+ attr_reader :functions
30
+
31
+ # @param command [Riker::Command]
32
+ def initialize(command)
33
+ @command = command
34
+ @functions = DEFAULT_FUNCTIONS.map { |func| func.new(command) }
35
+ end
36
+
37
+ # @param klass [Class]
38
+ def write!(klass)
39
+ klass.define_method(:execute, &command.execute_block)
40
+ define_default_setters!(klass)
41
+ define_attr_readers!(klass)
42
+ write_functions!(klass)
43
+ include_instance_methods!(klass)
44
+ end
45
+
46
+ private
47
+
48
+ # @param klass [Class]
49
+ def write_functions!(klass)
50
+ functions.each do |function|
51
+ details = function.details
52
+ klass.class_eval(details.code, details.file, details.line)
53
+ end
54
+ end
55
+
56
+ # @param klass [Class]
57
+ def define_attr_readers!(klass)
58
+ klass.attr_reader(*command.parameters.map(&:name))
59
+ end
60
+
61
+ # @param klass [Class]
62
+ def define_default_setters!(klass)
63
+ command.parameters.each do |param|
64
+ param.default.build_default_function!(klass)
65
+ end
66
+ end
67
+
68
+ # @param klass [Class]
69
+ def include_instance_methods!(klass)
70
+ INSTANCE_METHOD_MODULES.each do |mod|
71
+ klass.include(mod)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Run!
6
+ #
7
+ # Represents the `initialize` method for your command
8
+ #
9
+ class InitializeFunction < Function
10
+ # @return [Symbol]
11
+ def name
12
+ :initialize
13
+ end
14
+
15
+ # @return [Riker::Command::FunctionDetails]
16
+ def details
17
+ FunctionDetails.new(<<~RUBY, __FILE__, __LINE__ + 1)
18
+ def initialize(#{command.parameters.ctor_args}) # def initialize(foo:)
19
+ #{command.parameters.variable_sets} # @foo = foo
20
+ end # end
21
+ RUBY
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Command Parameters
6
+ #
7
+ # This is responsible for keeping track of the command's
8
+ # parameters. This includes how they are used and applied
9
+ # to the construction of a command.
10
+ #
11
+ class Parameters
12
+ include Enumerable
13
+ class ParamNameTaken < ::Riker::Error; end
14
+ class InvalidParamName < ::Riker::Error; end
15
+ class ReservedAttributeName < ::Riker::Error; end
16
+
17
+ RESERVED_ATTR_NAMES = %i[
18
+ errors
19
+ ].to_set.freeze
20
+
21
+ def initialize
22
+ # @var [Hash<Symbol, Parameter>]
23
+ @params = {}
24
+ end
25
+
26
+ # @param name [Symbol]
27
+ # @return [Parameters]
28
+ #
29
+ def add(name, **options)
30
+ validate_name!(name)
31
+ @params[name] = Parameter.new(name, **options)
32
+
33
+ self
34
+ end
35
+
36
+ # @return [String]
37
+ def ctor_args
38
+ map(&:ctor_arg).join(', ')
39
+ end
40
+
41
+ # @return [String]
42
+ def variable_sets
43
+ map(&:variable_set).join("\n")
44
+ end
45
+
46
+ # @yield [Parameter]
47
+ def each(&block)
48
+ @params.values.each(&block)
49
+ end
50
+
51
+ private
52
+
53
+ def validate_name!(name)
54
+ raise InvalidParamName unless name.is_a?(Symbol)
55
+ raise ReservedAttributeName if RESERVED_ATTR_NAMES.include?(name)
56
+ raise ParamNameTaken if @params.key?(name)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Run!
6
+ #
7
+ # Represents the `run!` static method for your command
8
+ #
9
+ class RunBangFunction < Function
10
+ # @return [Symbol]
11
+ def name
12
+ :run!
13
+ end
14
+
15
+ # @return [Riker::Command::FunctionDetails]
16
+ def details
17
+ FunctionDetails.new(<<~RUBY, __FILE__, __LINE__ + 1)
18
+ def self.run!(**arguments) # def self.run!(**arguments)
19
+ command = new(**arguments) # command = new(**arguments)
20
+ result = command.execute # result = command.execute
21
+ if command.errored? # if command.errored?
22
+ command.errors.raise! # command.errors.raise!
23
+ end # end
24
+ result # result
25
+ end # end
26
+ RUBY
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Command
5
+ # Run!
6
+ #
7
+ # Represents the `run!` static method for your command
8
+ #
9
+ class RunFunction < Function
10
+ # @return [Symbol]
11
+ def name
12
+ :run
13
+ end
14
+
15
+ # @return [Riker::Command::FunctionDetails]
16
+ def details
17
+ FunctionDetails.new(<<~RUBY, __FILE__, __LINE__ + 1)
18
+ def self.run(**arguments) # def self.run!(**arguments)
19
+ command = new(**arguments) # command = new(**arguments)
20
+ result = command.execute # result = command.execute
21
+ if command.errored? # if command.errored?
22
+ Riker::Outcome.invalid(command.errors) # Riker::Outcome.invalid(command.errors)
23
+ else # else
24
+ Riker::Outcome.valid(result) # Riker::Outcome.valid(result)
25
+ end # end
26
+ end # end
27
+ RUBY
28
+ end
29
+ end
30
+ end
31
+ end
data/lib/riker/command.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'command/parameters'
4
+ require_relative 'command/fallible_methods'
5
+ require_relative 'command/function'
6
+ require_relative 'command/function_details'
7
+ require_relative 'command/function_writer'
8
+
3
9
  module Riker
4
10
  # Command Builder
5
11
  #
@@ -7,56 +13,18 @@ module Riker
7
13
  # track of the build of a command in your application
8
14
  #
9
15
  class Command
10
- # @return [Riker::CommandParameters]
16
+ # @return [Riker::Command::Parameters]
11
17
  attr_reader :parameters
12
18
 
19
+ # @return [Riker::Command::FunctionWriter]
20
+ attr_reader :function_writer
21
+
13
22
  # @return [Proc, nil]
14
23
  attr_accessor :execute_block
15
24
 
16
25
  def initialize
17
- @parameters = CommandParameters.new
18
- end
19
-
20
- # @param klass [Class]
21
- def build!(klass)
22
- klass.define_method(:execute, &execute_block)
23
- define_default_setters!(klass)
24
- define_init!(klass)
25
- define_run_bang!(klass)
26
- define_attr_readers!(klass)
27
- end
28
-
29
- private
30
-
31
- # @param klass [Class]
32
- def define_init!(klass)
33
- klass.class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
34
- def initialize(#{parameters.ctor_args}) # def initialize(foo:)
35
- #{parameters.variable_sets} # @foo = foo
36
- end # end
37
- RUBY
38
- end
39
-
40
- # @param klass [Class]
41
- def define_run_bang!(klass)
42
- klass.class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
43
- def self.run!(**arguments) # def initialize(**arguments)
44
- command = new(**arguments) # command = new(**arguments)
45
- command.execute # command.execute
46
- end # end
47
- RUBY
48
- end
49
-
50
- # @param klass [Class]
51
- def define_attr_readers!(klass)
52
- klass.attr_reader(*parameters.map(&:name))
53
- end
54
-
55
- # @param klass [Class]
56
- def define_default_setters!(klass)
57
- parameters.each do |param|
58
- param.default.build_default_function!(klass)
59
- end
26
+ @parameters = Parameters.new
27
+ @function_writer = FunctionWriter.new(self)
60
28
  end
61
29
  end
62
30
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Outcome
5
+ # Outcome Errors
6
+ #
7
+ # A wrapper to keep track of and report on errors
8
+ # that happened during the execution of a command.
9
+ #
10
+ class Errors
11
+ # @!method any?
12
+ # @return [Boolean]
13
+ # @!method none?
14
+ # @return [Boolean]
15
+ extend Forwardable
16
+ def_delegators :@errors, :any?, :none?
17
+
18
+ def initialize
19
+ @errors = Hash.new { |hash, key| hash[key] = [] }
20
+ end
21
+
22
+ # @param key [Symbol]
23
+ # @param error [String]
24
+ # @return [void]
25
+ def add(key, error)
26
+ @errors[key] << error
27
+
28
+ nil
29
+ end
30
+
31
+ # @return [Array<String>]
32
+ def messages
33
+ @errors.values.flatten!
34
+ end
35
+
36
+ # @raise [Riker::ExecutionError]
37
+ def raise!
38
+ raise as_execution_error
39
+ end
40
+
41
+ private
42
+
43
+ def as_execution_error
44
+ Riker::Outcome::ExecutionError.new(self)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Outcome
5
+ # Execution Error
6
+ #
7
+ # This exception is raised when a problem has happened
8
+ # with your command. It is the result normall of having
9
+ # errors.
10
+ #
11
+ # @see Riker::Command::FallibleMethods
12
+ #
13
+ class ExecutionError < Error
14
+ # @return [Riker::Outcome::Errors]
15
+ attr_reader :errors
16
+
17
+ # @param errors [Riker::Outcome::Errors]
18
+ def initialize(errors)
19
+ super()
20
+ @errors = errors
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'outcome/errors'
4
+ require_relative 'outcome/execution_error'
5
+
6
+ module Riker
7
+ # Wrapped Outcome of a Command
8
+ #
9
+ # Commands may be fallible; and in that case
10
+ # they return an outcome that will either detail
11
+ # the errors that came up during execution or the
12
+ # expected data if it was success.
13
+ #
14
+ class Outcome
15
+ # @return [Object]
16
+ attr_reader :result
17
+
18
+ class << self
19
+ # @param result [Object]
20
+ # @return [Riker::Outcome]
21
+ def valid(result)
22
+ new(:valid, result)
23
+ end
24
+
25
+ def invalid(errors)
26
+ new(:invalid, errors)
27
+ end
28
+
29
+ private :new
30
+ end
31
+
32
+ # @param state [:valid, :invalid]
33
+ # @data [Object, Riker::Outcome::Errors]
34
+ def initialize(state, data)
35
+ if state == :valid
36
+ @result = data
37
+ else
38
+ @errors = data
39
+ end
40
+ end
41
+
42
+ # @return [Boolean]
43
+ def valid?
44
+ return true unless defined?(@errors)
45
+
46
+ @errors.none?
47
+ end
48
+
49
+ # @return [Boolean]
50
+ def invalid?
51
+ return false unless defined?(@errors)
52
+
53
+ @errors.any?
54
+ end
55
+
56
+ # @return [Riker::Outcome::Errors]
57
+ def errors
58
+ @errors ||= Errors.new
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Riker
4
+ class Parameter
5
+ # Default Parameter Value
6
+ #
7
+ # Sometimes we want to have parameters default to sensible
8
+ # defaults. This class's responsibility is to keep track
9
+ # this and set's up work to ensure defaults setup properly.
10
+ #
11
+ class DefaultValue
12
+ # @return [Symbol]
13
+ attr_reader :name
14
+
15
+ # @return [BasicObject]
16
+ def self.no_value
17
+ :__no_default__
18
+ end
19
+
20
+ # @param name [Symbol]
21
+ # @param value [Object, Proc]
22
+ def initialize(name, value)
23
+ @name = name
24
+ @present = value != :__no_default__
25
+ @value_proc = value.is_a?(Proc) ? value : -> { value }
26
+ end
27
+
28
+ # @return [Boolean]
29
+ def present?
30
+ @present
31
+ end
32
+
33
+ # @return [Symbol, nil]
34
+ def function_name
35
+ return unless present?
36
+
37
+ @function_name ||= :"default_value_for_#{name}"
38
+ end
39
+
40
+ def build_default_function!(klass)
41
+ return unless present?
42
+
43
+ klass.define_method(function_name, &@value_proc)
44
+ klass.send(:private, function_name)
45
+ end
46
+ end
47
+ end
48
+ end
data/lib/riker/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Riker
4
- VERSION = '0.1.0.pre3'
4
+ VERSION = '0.1.0.pre5'
5
5
  end
data/lib/riker.rb CHANGED
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'forwardable'
4
+ require 'set'
5
+
3
6
  require_relative 'riker/version'
4
7
  require_relative 'riker/error'
5
8
  require_relative 'riker/command'
6
- require_relative 'riker/command_parameters'
7
9
  require_relative 'riker/parameter'
10
+ require_relative 'riker/outcome'
8
11
 
9
12
  # The Commander of the USS Enterprise
10
13
  module Riker
@@ -26,6 +29,6 @@ module Riker
26
29
  raise Error, "execute block already called for #{self}!" if command.execute_block
27
30
 
28
31
  command.execute_block = block
29
- command.build!(self)
32
+ command.function_writer.write!(self)
30
33
  end
31
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre3
4
+ version: 0.1.0.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Falk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-28 00:00:00.000000000 Z
11
+ date: 2022-10-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: High-Performance, Dependency-Free Command Pattern For Ruby
14
14
  email:
@@ -29,9 +29,20 @@ files:
29
29
  - bin/setup
30
30
  - lib/riker.rb
31
31
  - lib/riker/command.rb
32
- - lib/riker/command_parameters.rb
32
+ - lib/riker/command/fallible_methods.rb
33
+ - lib/riker/command/function.rb
34
+ - lib/riker/command/function_details.rb
35
+ - lib/riker/command/function_writer.rb
36
+ - lib/riker/command/initialize_function.rb
37
+ - lib/riker/command/parameters.rb
38
+ - lib/riker/command/run_bang_function.rb
39
+ - lib/riker/command/run_function.rb
33
40
  - lib/riker/error.rb
41
+ - lib/riker/outcome.rb
42
+ - lib/riker/outcome/errors.rb
43
+ - lib/riker/outcome/execution_error.rb
34
44
  - lib/riker/parameter.rb
45
+ - lib/riker/parameter/default_value.rb
35
46
  - lib/riker/version.rb
36
47
  - sig/riker.rbs
37
48
  homepage:
@@ -55,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
66
  - !ruby/object:Gem::Version
56
67
  version: 1.3.1
57
68
  requirements: []
58
- rubygems_version: 3.1.6
69
+ rubygems_version: 3.3.7
59
70
  signing_key:
60
71
  specification_version: 4
61
72
  summary: High-Performance, Dependency-Free Command Pattern For Ruby
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Riker
4
- # Command Parameters
5
- #
6
- # This is responsible for keeping track of the command's
7
- # parameters. This includes how they are used and applied
8
- # to the construction of a command.
9
- #
10
- class CommandParameters
11
- include Enumerable
12
- class ParamNameTaken < ::Riker::Error; end
13
- class InvalidParamName < ::Riker::Error; end
14
-
15
- def initialize
16
- # @var [Hash<Symbol, Parameter>]
17
- @params = {}
18
- end
19
-
20
- # @param name [Symbol]
21
- # @return [Parameters]
22
- #
23
- def add(name, **options)
24
- validate_name!(name)
25
- @params[name] = Parameter.new(name, **options)
26
-
27
- self
28
- end
29
-
30
- # @return [String]
31
- def ctor_args
32
- map(&:ctor_arg).join(', ')
33
- end
34
-
35
- # @return [String]
36
- def variable_sets
37
- map(&:variable_set).join("\n")
38
- end
39
-
40
- # @yield [Parameter]
41
- def each(&block)
42
- @params.values.each(&block)
43
- end
44
-
45
- private
46
-
47
- def validate_name!(name)
48
- raise InvalidParamName unless name.is_a?(Symbol)
49
- raise ParamNameTaken if @params.key?(name)
50
- end
51
- end
52
- end