sleeping_king_studios-tools 1.3.0.rc.0 → 1.3.0.rc.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: ddf9748934072d1e7acf8ae748029ed8d616c46fd7d0a502499f0b54bc4e5d1b
4
- data.tar.gz: bae72b5b57afe8404d45aab67ee59a5e8643b3656820e915c535b934016ee0d3
3
+ metadata.gz: 4939601ed132d3b370114ce53c547e220277c715eb1d442dc20566049f041bea
4
+ data.tar.gz: f5cf620154ef2245749693dc5da447adb6fc0e2644bf3aa1094d289881a32338
5
5
  SHA512:
6
- metadata.gz: 6de4c073168e77a204afc0a1b4cc7e873619fbb9796df24177b7c2125be120df29e22034a690da73f1998822e10667d473bebfcdfb4adcd4da0a6dbea3f796c5
7
- data.tar.gz: 999e795763737b1f79be6d0884f162cf436d116c7319cd6d66d4934e3bbb2048249bf4d7e9c632379d2d2e5aa01525bf0ddcc52318e5d146153af7971fa945e6
6
+ metadata.gz: 0da898a1ae8bd177700cbd6d3736fe171a534ad2f9b7e3c934f9e033c4b61136e4996dc8d375c98706a83b4ef573531901a3fa4de830a29fc3bff6c39f251307
7
+ data.tar.gz: 050d5c3e8ae855129dc5aa0d426038bda2bd43706282c3b89e418e56d69973781d9996002168e15bcdc29ae0acd387494dc260402351058d76400c0ee4ace564
data/CHANGELOG.md CHANGED
@@ -91,6 +91,10 @@ Added keyword support to `ConstantMap.new`.
91
91
 
92
92
  Corrected the scope of `Mixin#included` and `Mixin#prepended` to be `private`.
93
93
 
94
+ #### HeritableData
95
+
96
+ Added `Toolbox::HeritableData`, which allows for defining `Data` subclasses with inheritable members and methods.
97
+
94
98
  #### Initializer
95
99
 
96
100
  Added `Toolbox::Initializer`, used for defining a one-time initialization for a library or project.
@@ -22,7 +22,7 @@ module SleepingKingStudios::Tools
22
22
  end
23
23
 
24
24
  # Data class representing a single node in the registry tree.
25
- Node = Struct.new(:children, :scope, :strategy, keyword_init: true) do
25
+ Node = Struct.new(:children, :scope, :strategy) do
26
26
  # @param scope [String] the scope for the registry node.
27
27
  # @param strategy [SleepingKingStudios::Tools::Messages::Strategy] the
28
28
  # strategy defined for the node, if any.
@@ -0,0 +1,198 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sleeping_king_studios/tools/toolbox'
4
+
5
+ module SleepingKingStudios::Tools::Toolbox
6
+ # Mixin to allow defining subclasses of Data classes.
7
+ module HeritableData
8
+ # Methods prepended onto the singleton class when including HeritableData.
9
+ module ClassMethods
10
+ # Compares `self` and `other`.
11
+ #
12
+ # @param other [Object] the object to compare.
13
+ #
14
+ # @return [true] if self is a subclass of other, or if self inherits Data
15
+ # members and methods from other.
16
+ # @return [false] if self and other are the same class, if other is a
17
+ # subclass of self, or if other inherits Data members and methods from
18
+ # self.
19
+ # @return [nil] if none of the above is true.
20
+ def <(other)
21
+ (self <=> other)&.then { |cmp| cmp == -1 }
22
+ end
23
+
24
+ # Compares `self` and `other`.
25
+ #
26
+ # @param other [Object] the object to compare.
27
+ #
28
+ # @return [true] if self and other are the same class, if self is a
29
+ # subclass of other, or if self inherits Data members and methods from
30
+ # other.
31
+ # @return [false] if other is a subclass of self, or if other inherits
32
+ # Data members and methods from self.
33
+ # @return [nil] if none of the above is true.
34
+ def <=(other)
35
+ (self <=> other)&.then { |cmp| cmp < 1 }
36
+ end
37
+
38
+ # Compares `self` and `other`.
39
+ #
40
+ # @param other [Object] the object to compare.
41
+ #
42
+ # @return [-1] if self is a subclass of other, or if self inherits Data
43
+ # members and methods from other.
44
+ # @return [0] if self and other are the same class.
45
+ # @return [1] if self is a parent class of other, or if other inherits
46
+ # Data members and methods from self.
47
+ # @return [nil] if none of the above is true.
48
+ def <=>(other)
49
+ return super unless other.is_a?(Class)
50
+
51
+ return -1 if other.equal?(Data)
52
+ return 0 if other.equal?(self)
53
+
54
+ return nil unless other.const_defined?(:HeritableMethods)
55
+
56
+ return -1 if include?(other::HeritableMethods)
57
+ return 1 if other.include?(self::HeritableMethods)
58
+
59
+ nil
60
+ end
61
+
62
+ # @return [true] if the object is an instance of the data class, or if the
63
+ # object is an instance of a Data class that inherits members and
64
+ # methods from self.
65
+ def ===(object)
66
+ return true if super
67
+
68
+ (self > object.class) || false
69
+ end
70
+
71
+ # Compares `self` and `other`.
72
+ #
73
+ # @param other [Object] the object to compare.
74
+ #
75
+ # @return [true] if other is a subclass of other, or if other inherits
76
+ # Data members and methods from self.
77
+ # @return [false] if self and other are the same class, if self is a
78
+ # subclass of other, or if self inherits Data members and methods from
79
+ # other.
80
+ # @return [nil] if none of the above is true.
81
+ def >(other)
82
+ (self <=> other)&.then { |cmp| cmp == 1 }
83
+ end
84
+
85
+ # Compares `self` and `other`.
86
+ #
87
+ # @param other [Object] the object to compare.
88
+ #
89
+ # @return [true] if self and other are the same class, if other is a
90
+ # subclass of other, or if other inherits Data members and methods from
91
+ # self.
92
+ # @return [false] if self is a subclass of other, or if self inherits Data
93
+ # members and methods from other.
94
+ # @return [nil] if none of the above is true.
95
+ def >=(other)
96
+ (self <=> other)&.then { |cmp| cmp > -1 }
97
+ end
98
+
99
+ # Defines a new Data class including the members/methods of this class.
100
+ #
101
+ # The defined data class will include HeritableData, and will be able to
102
+ # define it's own Data types using this method.
103
+ #
104
+ # @param symbols [Array<Symbol>] additional Data members to define. Any
105
+ # members listed here will be appended to the members defined on the
106
+ # parent Data class.
107
+ #
108
+ # @yield additional methods to define on the new Data class.
109
+ def define(*symbols, &)
110
+ HeritableData.define(*symbols, parent_class: self, &)
111
+ end
112
+ end
113
+
114
+ # Custom module used to propagate heritable methods across Data classes.
115
+ #
116
+ # @private
117
+ class HeritableMethods < Module
118
+ # @param parent_class [Class, nil] the parent data class, if any.
119
+ #
120
+ # @yield additional methods to define on the Data class.
121
+ def initialize(parent_class: nil, &methods)
122
+ super(&nil)
123
+
124
+ @parent_class = parent_class
125
+
126
+ class_exec(&methods) if methods
127
+ end
128
+
129
+ # @return [Class, nil] the parent data class.
130
+ attr_reader :parent_class
131
+
132
+ private
133
+
134
+ def each_ancestor
135
+ return enum_for(:each_ancestor) unless block_given?
136
+
137
+ ancestor = parent_class
138
+
139
+ while ancestor
140
+ yield ancestor::HeritableMethods
141
+
142
+ ancestor = ancestor::HeritableMethods.parent_class
143
+ end
144
+ end
145
+
146
+ def included(other)
147
+ super
148
+
149
+ each_ancestor { |ancestor| other.include(ancestor) }
150
+ end
151
+ end
152
+
153
+ class << self
154
+ # Defines a new heritable Data class.
155
+ #
156
+ # @param symbols [Array<Symbol>] Data members to define.
157
+ # @param parent_class [Class] the parent class to inherit members and
158
+ # methods from.
159
+ #
160
+ # @yield additional methods to define on the new Data class.
161
+ def define(*symbols, parent_class: nil, &)
162
+ Data.define(*parent_class&.members, *symbols).tap do |data_class|
163
+ data_class.include(HeritableData)
164
+
165
+ define_mixin_for(data_class, parent_class, &)
166
+ end
167
+ end
168
+
169
+ private
170
+
171
+ def define_mixin_for(data_class, parent_class = nil, &)
172
+ data_class.const_set(
173
+ :HeritableMethods,
174
+ HeritableData::HeritableMethods.new(parent_class:, &)
175
+ )
176
+
177
+ data_class.include(data_class::HeritableMethods)
178
+ end
179
+
180
+ def included(other)
181
+ super
182
+
183
+ other.singleton_class.prepend(ClassMethods)
184
+ end
185
+ end
186
+
187
+ # Checks if the object class inherits from type.
188
+ #
189
+ # @param type [Module] the type to check.
190
+ #
191
+ # @return [true] if the object class inherits from type, or if the object
192
+ # class inherits members and methods from the given type.
193
+ def is_a?(type)
194
+ super || self.class < type || false
195
+ end
196
+ alias kind_of? is_a?
197
+ end
198
+ end
@@ -7,6 +7,8 @@ module SleepingKingStudios::Tools
7
7
  module Toolbox
8
8
  autoload :ConstantMap,
9
9
  'sleeping_king_studios/tools/toolbox/constant_map'
10
+ autoload :HeritableData,
11
+ 'sleeping_king_studios/tools/toolbox/heritable_data'
10
12
  autoload :Inflector,
11
13
  'sleeping_king_studios/tools/toolbox/inflector'
12
14
  autoload :Initializer,
@@ -15,7 +15,7 @@ module SleepingKingStudios
15
15
  # Prerelease version.
16
16
  PRERELEASE = :rc
17
17
  # Build metadata.
18
- BUILD = 0
18
+ BUILD = 1
19
19
 
20
20
  class << self
21
21
  # Generates the gem version string from the Version constants.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sleeping_king_studios-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0.rc.0
4
+ version: 1.3.0.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
@@ -42,6 +42,7 @@ files:
42
42
  - lib/sleeping_king_studios/tools/toolbelt.rb
43
43
  - lib/sleeping_king_studios/tools/toolbox.rb
44
44
  - lib/sleeping_king_studios/tools/toolbox/constant_map.rb
45
+ - lib/sleeping_king_studios/tools/toolbox/heritable_data.rb
45
46
  - lib/sleeping_king_studios/tools/toolbox/inflector.rb
46
47
  - lib/sleeping_king_studios/tools/toolbox/inflector/rules.rb
47
48
  - lib/sleeping_king_studios/tools/toolbox/initializer.rb