sleeping_king_studios-tools 0.7.0.beta.1 → 1.0.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +41 -5
  3. data/CODE_OF_CONDUCT.md +132 -0
  4. data/DEVELOPMENT.md +7 -16
  5. data/LICENSE +1 -1
  6. data/README.md +71 -145
  7. data/lib/sleeping_king_studios/tools.rb +12 -6
  8. data/lib/sleeping_king_studios/tools/array_tools.rb +86 -58
  9. data/lib/sleeping_king_studios/tools/base.rb +20 -0
  10. data/lib/sleeping_king_studios/tools/core_tools.rb +78 -19
  11. data/lib/sleeping_king_studios/tools/hash_tools.rb +69 -42
  12. data/lib/sleeping_king_studios/tools/integer_tools.rb +97 -55
  13. data/lib/sleeping_king_studios/tools/object_tools.rb +75 -52
  14. data/lib/sleeping_king_studios/tools/string_tools.rb +69 -96
  15. data/lib/sleeping_king_studios/tools/toolbelt.rb +44 -23
  16. data/lib/sleeping_king_studios/tools/toolbox.rb +2 -2
  17. data/lib/sleeping_king_studios/tools/toolbox/constant_map.rb +75 -74
  18. data/lib/sleeping_king_studios/tools/toolbox/inflector.rb +124 -0
  19. data/lib/sleeping_king_studios/tools/toolbox/inflector/rules.rb +171 -0
  20. data/lib/sleeping_king_studios/tools/toolbox/mixin.rb +11 -11
  21. data/lib/sleeping_king_studios/tools/toolbox/semantic_version.rb +15 -14
  22. data/lib/sleeping_king_studios/tools/version.rb +15 -11
  23. metadata +103 -34
  24. data/lib/sleeping_king_studios/tools/all.rb +0 -5
  25. data/lib/sleeping_king_studios/tools/enumerable_tools.rb +0 -8
  26. data/lib/sleeping_king_studios/tools/semantic_version.rb +0 -15
  27. data/lib/sleeping_king_studios/tools/string_tools/plural_inflector.rb +0 -185
  28. data/lib/sleeping_king_studios/tools/toolbox/configuration.rb +0 -197
  29. data/lib/sleeping_king_studios/tools/toolbox/delegator.rb +0 -175
@@ -1,197 +0,0 @@
1
- # lib/sleeping_king_studios/tools/toolbox/configuration.rb
2
-
3
- require 'sleeping_king_studios/tools/toolbox'
4
-
5
- module SleepingKingStudios::Tools::Toolbox
6
- class Configuration
7
- module ClassMethods
8
- DEFAULT_OPTION = Object.new.freeze
9
-
10
- # Defines a nested namespace for the configuration object.
11
- def namespace namespace_name, &block
12
- define_namespace namespace_name, &block
13
- end # method namespace
14
-
15
- # Defines an option for the configuration object.
16
- def option option_name, allow_nil: false, default: DEFAULT_OPTION, enum: nil
17
- options = {
18
- :allow_nil => allow_nil,
19
- :default => default,
20
- :enum => enum
21
- } # end hash
22
-
23
- define_accessor option_name, options
24
- define_mutator option_name, options
25
- end # class method option
26
-
27
- private
28
-
29
- def define_accessor option_name, options
30
- define_method option_name do
31
- __get_value__(option_name, options)
32
- end # method option_name
33
- end # method define_accessor
34
-
35
- def define_mutator option_name, options
36
- writer_name = :"#{option_name}="
37
-
38
- define_method writer_name do |value|
39
- __set_value__(option_name, value, options)
40
- end # method option_name=
41
- end # method define_mutator
42
-
43
- def define_namespace namespace_name, &block
44
- namespace =
45
- Class.new(SleepingKingStudios::Tools::Toolbox::Configuration)
46
- namespace.instance_exec namespace, &block if block_given?
47
-
48
- define_method namespace_name do
49
- if instance_variable_defined?(:"@#{namespace_name}")
50
- return instance_variable_get(:"@#{namespace_name}")
51
- end # if
52
-
53
- data = __get_value__(namespace_name, :default => Object.new)
54
- config = namespace.new(data)
55
-
56
- config.__root_namespace__ = __root_namespace__ || self
57
-
58
- instance_variable_set(:"@#{namespace_name}", config)
59
-
60
- config
61
- end # method namespace_name
62
- end # method define_namespace
63
- end # module
64
- extend ClassMethods
65
-
66
- DEFAULT_OPTION = ClassMethods::DEFAULT_OPTION
67
-
68
- # @param data [Hash, Object] The data source used to populate configuration
69
- # values. Can be a Hash or a data object. If the data source is nil, or no
70
- # data source is given, values will be set to their respective defaults.
71
- def initialize data = nil
72
- @__data__ = __objectify_data__(data)
73
- @__root_namespace__ = self
74
-
75
- yield(singleton_class) if block_given?
76
- end # constructor
77
-
78
- def [] key
79
- send(key) if respond_to?(key)
80
- end # method []
81
-
82
- def []= key, value
83
- send(:"#{key}=", value)
84
- end # method []=
85
-
86
- def dig *keys
87
- keys.reduce(self) do |hsh, key|
88
- value = hsh[key]
89
-
90
- return value if value.nil?
91
-
92
- value
93
- end # reduce
94
- end # method dig
95
-
96
- def fetch key, default = DEFAULT_OPTION
97
- return send(key) if respond_to?(key)
98
-
99
- return default unless default == DEFAULT_OPTION
100
-
101
- return yield if block_given?
102
-
103
- raise KeyError, 'key not found'
104
- end # method fetch
105
-
106
- protected
107
-
108
- attr_accessor :__root_namespace__
109
-
110
- private
111
-
112
- attr_reader :__data__
113
-
114
- def __blank_value__ value
115
- value.nil? || (value.respond_to?(:empty?) && value.empty?)
116
- end # method __blank_value__
117
-
118
- def __evaluate_default__ default
119
- default.is_a?(Proc) ? __root_namespace__.instance_exec(&default) : default
120
- end # method __evaluate_default__
121
-
122
- def __get_value__ name, options
123
- default_given = options[:default] != DEFAULT_OPTION
124
-
125
- if __data__.respond_to?(name)
126
- value = __data__.send name
127
-
128
- if value.nil? && default_given
129
- value = __evaluate_default__(options[:default])
130
- end # if
131
-
132
- __validate_value__ value, options
133
-
134
- value
135
- elsif instance_variable_defined?(:"@#{name}")
136
- # Recall values locally if data source is immutable.
137
- return instance_variable_get(:"@#{name}")
138
- elsif default_given
139
- value = __evaluate_default__(options[:default])
140
-
141
- __validate_value__ value, options
142
-
143
- value
144
- else
145
- __validate_value__ nil, options
146
-
147
- nil
148
- end # if-else
149
- end # method __get_value__
150
-
151
- def __objectify_data__ data
152
- return data unless data.is_a?(Hash)
153
-
154
- return Object.new if data.empty?
155
-
156
- obj = Struct.new(*data.keys).new
157
-
158
- data.each do |key, value|
159
- val = value.is_a?(Hash) ? __objectify_data__(value) : value
160
-
161
- obj.send :"#{key}=", val
162
- end # each
163
-
164
- obj
165
- end # method __objectify_data__
166
-
167
- def __set_value__ name, value, options
168
- writer_name = :"#{name}="
169
-
170
- __validate_value__ value, options
171
-
172
- if __data__.respond_to?(writer_name)
173
- __data__.send(writer_name, value)
174
- else
175
- # Store values locally if data source is immutable.
176
- instance_variable_set(:"@#{name}", value)
177
- end # if-else
178
- end # method __set_value__
179
-
180
- def __validate_value__ value, options
181
- return if __blank_value__(value) && options[:allow_nil]
182
-
183
- if options[:enum] && !options[:enum].include?(value)
184
- array_tools = ::SleepingKingStudios::Tools::ArrayTools
185
- valid_options =
186
- array_tools.
187
- humanize_list(
188
- options[:enum].map(&:inspect),
189
- :last_separator => ' or '
190
- ) # end humanize_list
191
-
192
- raise RuntimeError,
193
- "expected option to be #{valid_options}, but was #{value.inspect}"
194
- end # if
195
- end # method __validate_value__
196
- end # class
197
- end # module
@@ -1,175 +0,0 @@
1
- # lib/sleeping_king_studios/tools/toolbox/delegator.rb
2
-
3
- require 'sleeping_king_studios/tools/toolbox'
4
-
5
- module SleepingKingStudios::Tools::Toolbox
6
- # Module for extending classes with basic delegation. Supports passing
7
- # arguments, keywords, and blocks to the delegated method.
8
- #
9
- # @example
10
- # class MyClass
11
- # extend SleepingKingStudios::Tools::Delegator
12
- #
13
- # delegate :my_method, :to => MyService
14
- # end # class
15
- module Delegator
16
- # Defines a wrapper method to delegate implementation of the specified
17
- # method or methods to an object, to the object at another specified method,
18
- # or to the object at a specified instance variable.
19
- #
20
- # @example Delegate to an object
21
- # class MyModule
22
- # extend SleepingKingStudios::Tools::Toolbox::Delegator
23
- #
24
- # delegate :my_method, :to => MyService
25
- # end # class
26
- #
27
- # @example Delegate to a method
28
- # class MyModule
29
- # extend SleepingKingStudios::Tools::Toolbox::Delegator
30
- #
31
- # def my_service
32
- # MyService.new
33
- # end # method my_service
34
- #
35
- # delegate :my_method, :to => :my_service
36
- # end # class
37
- #
38
- # @example Delegate to an instance variable
39
- # class MyModule
40
- # extend SleepingKingStudios::Tools::Toolbox::Delegator
41
- #
42
- # def initialize
43
- # @my_service = MyService.new
44
- # end # constructor
45
- #
46
- # delegate :my_method, :to => :@my_service
47
- # end # class
48
- #
49
- # @param method_names [Array<String, Symbol>] The names of the methods to
50
- # delegate.
51
- # @param to [Object, String, Symbol] The object, method, or instance
52
- # variable to delegate to. If the object is not a string or symbol, the
53
- # generated method will call `method_name` on the object. If the object is
54
- # a string or symbol, but does not start with an `@`, the generated method
55
- # will call the method of that name on the instance, and then call
56
- # `method_name` on the result. If the object is a string or symbol and
57
- # does start with an `@`, the generated method will get the instance
58
- # variable of that name and call `method_name` on the result.
59
- #
60
- # @raise ArgumentError if no delegate is specified.
61
- def delegate *method_names, to: nil, allow_nil: false
62
- raise ArgumentError.new('must specify a delegate') if to.nil? && !allow_nil
63
-
64
- method_names.each do |method_name|
65
- delegate_method method_name, to, { :allow_nil => !!allow_nil }
66
- end # each
67
- end # method delegate
68
-
69
- # Wraps a delegate object by automatically delegating each method that is
70
- # defined on the delegate class from the instance to the delegate. The
71
- # delegate can be specified with an object literal or with the name of an
72
- # instance method or instance variable.
73
- #
74
- # Only methods that are defined at the time #wrap_delegate is called will be
75
- # delegated, so make sure to call #wrap_delegate after loading any gems or
76
- # libraries that extend your delegate class, such as ActiveSupport.
77
- #
78
- # @example Create a class that wraps a Hash
79
- # class Errors
80
- # extend SleepingKingStudios::Tools::Delegator
81
- #
82
- # wrap_delegate Hash.new { |hsh, key| hsh[key] = Errors.new }, :klass => Hash
83
- #
84
- # def messages
85
- # @messages ||= []
86
- # end # method messages
87
- # end # class
88
- #
89
- # errors = Errors.new
90
- # errors[:post].messages << "title can't be blank"
91
- #
92
- # @param target [Object, String, Symbol] The object, method, or instance
93
- # variable to delegate to. If the object is not a string or symbol, the
94
- # generated method will call each method on the object. If the object is
95
- # a string or symbol, but does not start with an `@`, the generated method
96
- # will call the method of that name on the instance, and then call
97
- # each method on the result. If the object is a string or symbol and
98
- # does start with an `@`, the generated method will get the instance
99
- # variable of that name and call each method on the result.
100
- # @param klass [Module] The class or module whose methods are delegated to
101
- # the target. If target is the name of an instance variable or an instance
102
- # method, the klass must be specified. If target is an object literal, the
103
- # klass is optional, in which case all methods from the target will be
104
- # delegated to the target.
105
- # @param except [Array<String, Symbol>] An optional list of method names.
106
- # Any names on the list will not be delegated, even if the method is
107
- # defined by the klass or defined on the target literal.
108
- # @param only [Array<String, Symbol>] An optional list of method names.
109
- # Only names on the list will be delegated, and only if the method is
110
- # defined by the klass or defined on the target literal.
111
- #
112
- # @raise ArgumentError if no delegate is specified.
113
- # @raise ArgumentError if the target is the name of an instance method or an
114
- # instance variable and no klass is specified.
115
- # @raise ArgumentError if the target is an object literal that does not
116
- # belong to the specified klass.
117
- #
118
- # @see #delegate
119
- def wrap_delegate target, klass: nil, except: [], only: []
120
- if klass.is_a?(Module)
121
- unless target.is_a?(String) || target.is_a?(Symbol) || target.is_a?(klass)
122
- raise ArgumentError.new "expected delegate to be a #{klass.name}"
123
- end # unless
124
-
125
- method_names = klass.instance_methods - Object.instance_methods
126
- elsif target.is_a?(String) || target.is_a?(Symbol)
127
- raise ArgumentError.new 'must specify a delegate class'
128
- else
129
- method_names = target.methods - Object.new.methods
130
- end # if-elsif-else
131
-
132
- if except.is_a?(Array) && !except.empty?
133
- method_names = method_names - except.map(&:intern)
134
- end # if
135
-
136
- if only.is_a?(Array) && !only.empty?
137
- method_names = method_names & only.map(&:intern)
138
- end # if
139
-
140
- delegate *method_names, :to => target
141
- end # method wrap_delegate
142
-
143
- private
144
-
145
- def delegate_method method_name, target, options = {}
146
- if target.is_a?(String) || target.is_a?(Symbol)
147
- target = target.intern
148
-
149
- if target.to_s =~ /\A@/
150
- define_method method_name do |*args, &block|
151
- receiver = instance_variable_get(target)
152
-
153
- return nil if receiver.nil? && options[:allow_nil]
154
-
155
- receiver.send(method_name, *args, &block)
156
- end # define_method
157
- else
158
- define_method method_name do |*args, &block|
159
- receiver = send(target)
160
-
161
- return nil if receiver.nil? && options[:allow_nil]
162
-
163
- receiver.send(method_name, *args, &block)
164
- end # define_method
165
- end # if-else
166
- else
167
- define_method method_name do |*args, &block|
168
- return nil if target.nil? && options[:allow_nil]
169
-
170
- target.send(method_name, *args, &block)
171
- end # define_method
172
- end # if
173
- end # method delegate_method
174
- end # module
175
- end # module