data_model 0.0.1 → 0.2.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.
- checksums.yaml +4 -4
- data/.editorconfig +6 -2
- data/.rubocop.yml +11 -2
- data/.ruby-version +2 -0
- data/Gemfile.lock +91 -54
- data/Guardfile +20 -0
- data/Rakefile +32 -0
- data/data_model.gemspec +52 -0
- data/lib/data_model/boolean.rb +7 -0
- data/lib/data_model/builtin/array.rb +73 -0
- data/lib/data_model/builtin/big_decimal.rb +64 -0
- data/lib/data_model/builtin/boolean.rb +37 -0
- data/lib/data_model/builtin/date.rb +60 -0
- data/lib/data_model/builtin/float.rb +64 -0
- data/lib/data_model/builtin/hash.rb +119 -0
- data/lib/data_model/builtin/integer.rb +64 -0
- data/lib/data_model/builtin/string.rb +88 -0
- data/lib/data_model/builtin/symbol.rb +64 -0
- data/lib/data_model/builtin/time.rb +60 -0
- data/lib/data_model/builtin.rb +23 -0
- data/lib/data_model/error.rb +107 -0
- data/lib/data_model/errors.rb +296 -0
- data/lib/data_model/fixtures/array.rb +61 -0
- data/lib/data_model/fixtures/big_decimal.rb +55 -0
- data/lib/data_model/fixtures/boolean.rb +35 -0
- data/lib/data_model/fixtures/date.rb +53 -0
- data/lib/data_model/fixtures/example.rb +29 -0
- data/lib/data_model/fixtures/float.rb +53 -0
- data/lib/data_model/fixtures/hash.rb +66 -0
- data/lib/data_model/fixtures/integer.rb +53 -0
- data/lib/data_model/fixtures/string.rb +110 -0
- data/lib/data_model/fixtures/symbol.rb +56 -0
- data/lib/data_model/fixtures/time.rb +53 -0
- data/lib/data_model/logging.rb +23 -0
- data/lib/data_model/model.rb +21 -44
- data/lib/data_model/scanner.rb +92 -56
- data/lib/data_model/testing/minitest.rb +79 -0
- data/lib/data_model/testing.rb +6 -0
- data/lib/data_model/type.rb +41 -39
- data/lib/data_model/type_registry.rb +68 -0
- data/lib/data_model/version.rb +3 -1
- data/lib/data_model.rb +32 -16
- data/sorbet/config +4 -0
- data/sorbet/rbi/annotations/rainbow.rbi +269 -0
- data/sorbet/rbi/gems/minitest@5.18.0.rbi +1491 -0
- data/sorbet/rbi/gems/zeitwerk.rbi +196 -0
- data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +966 -0
- data/sorbet/rbi/todo.rbi +5 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- metadata +139 -17
- data/config/sus.rb +0 -2
- data/fixtures/schema.rb +0 -14
- data/lib/data_model/registry.rb +0 -44
@@ -0,0 +1,68 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module DataModel
|
4
|
+
# TypeRegistry allows for different type implementations to be used by the scanner.
|
5
|
+
# It also acts as an error message registry, mostly for pragmatic reasons.
|
6
|
+
class TypeRegistry
|
7
|
+
include Errors
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
# Default types that will be used if alternative type map is not given
|
11
|
+
sig { returns(TTypeMap) }
|
12
|
+
def self.default_types
|
13
|
+
Builtin.types
|
14
|
+
end
|
15
|
+
|
16
|
+
# Singleton instance that will be used globally unless instances given
|
17
|
+
sig { params(types: TTypeMap, errors: T.nilable(TErrorMessages)).returns(TypeRegistry) }
|
18
|
+
def self.instance(types: default_types, errors: nil)
|
19
|
+
@instance ||= T.let(new(types:, errors:), T.nilable(TypeRegistry))
|
20
|
+
end
|
21
|
+
|
22
|
+
# Register a type on the global instance
|
23
|
+
sig { params(name: Symbol, type: T.class_of(Type)).void }
|
24
|
+
def self.register(name, type)
|
25
|
+
instance.register(name, type)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Instanciate a new type registry. Default errors will always be used, but additional
|
29
|
+
# errors can be registered.
|
30
|
+
sig { params(types: TTypeMap, errors: T.nilable(TErrorMessages)).void }
|
31
|
+
def initialize(types: self.class.default_types, errors: nil)
|
32
|
+
if errors
|
33
|
+
errors.each { |type, builder| register_error_message(type, &builder) }
|
34
|
+
end
|
35
|
+
|
36
|
+
@types = T.let({}, TTypeMap)
|
37
|
+
types.each { |(name, type)| register(name, type) }
|
38
|
+
end
|
39
|
+
|
40
|
+
# Register a type on this instance
|
41
|
+
sig { params(name: Symbol, type: T.class_of(Type)).void }
|
42
|
+
def register(name, type)
|
43
|
+
@types[name] = type
|
44
|
+
end
|
45
|
+
|
46
|
+
# Check if a type is registered
|
47
|
+
sig { params(name: Symbol).returns(T::Boolean) }
|
48
|
+
def type?(name)
|
49
|
+
@types.key?(name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Access and configure registered type
|
53
|
+
sig { params(name: Symbol, args: Type::TArguments, params: T.nilable(T::Array[Object])).returns(Type) }
|
54
|
+
def type(name, args: {}, params: nil)
|
55
|
+
if !type?(name)
|
56
|
+
raise "#{name} is not registered as a type"
|
57
|
+
end
|
58
|
+
|
59
|
+
t = @types.fetch(name).new(args, registry: self)
|
60
|
+
|
61
|
+
if params
|
62
|
+
t.configure(params)
|
63
|
+
end
|
64
|
+
|
65
|
+
return t
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/data_model/version.rb
CHANGED
data/lib/data_model.rb
CHANGED
@@ -1,28 +1,44 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
require "bigdecimal"
|
5
|
+
require "date"
|
6
|
+
require "time"
|
7
|
+
|
8
|
+
require "bundler/setup"
|
1
9
|
require "zeitwerk"
|
10
|
+
require "sorbet-runtime"
|
2
11
|
|
3
|
-
loader = Zeitwerk::Loader.for_gem
|
12
|
+
loader = T.let(Zeitwerk::Loader.for_gem, Zeitwerk::Loader)
|
4
13
|
loader.setup
|
5
14
|
|
6
15
|
module DataModel
|
16
|
+
extend T::Sig
|
7
17
|
extend self
|
8
18
|
|
9
|
-
|
10
|
-
|
11
|
-
err.empty? || err.values.all?(&:empty?)
|
12
|
-
end
|
19
|
+
TSchema = T.type_alias { T::Array[Object] }
|
20
|
+
TData = T.type_alias { Object }
|
13
21
|
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
# an error is a tuple of [error_type, error_context], where context
|
23
|
+
# provides additional information about the error
|
24
|
+
TError = T.type_alias { [Symbol, Object] }
|
17
25
|
|
18
|
-
|
19
|
-
|
20
|
-
|
26
|
+
# a map of symbol => type, suitable for sending to a TypeRegistry
|
27
|
+
TTypeMap = T.type_alias { T::Hash[Symbol, T.class_of(Type)] }
|
28
|
+
|
29
|
+
# Scan a schema and create a data model, which is a configured type.
|
30
|
+
sig { params(schema: TSchema, registry: TypeRegistry).returns(Model) }
|
31
|
+
def define(schema, registry: TypeRegistry.instance)
|
32
|
+
scanned = Scanner.scan(schema, registry)
|
33
|
+
|
34
|
+
type = registry.type(
|
35
|
+
scanned.type,
|
36
|
+
args: scanned.args,
|
37
|
+
params: scanned.params,
|
38
|
+
)
|
39
|
+
|
40
|
+
model = Model.new(schema, type)
|
21
41
|
|
22
|
-
|
23
|
-
if model in Array
|
24
|
-
model = Scanner.scan(model, registry)
|
25
|
-
end
|
26
|
-
model
|
42
|
+
return model
|
27
43
|
end
|
28
44
|
end
|
data/sorbet/config
ADDED
@@ -0,0 +1,269 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
# DO NOT EDIT MANUALLY
|
4
|
+
# This file was pulled from a central RBI files repository.
|
5
|
+
# Please run `bin/tapioca annotations` to update it.
|
6
|
+
|
7
|
+
module Rainbow
|
8
|
+
# @shim: https://github.com/sickill/rainbow/blob/master/lib/rainbow.rb#L10-L12
|
9
|
+
sig { returns(T::Boolean) }
|
10
|
+
attr_accessor :enabled
|
11
|
+
|
12
|
+
class Color
|
13
|
+
sig { returns(Symbol) }
|
14
|
+
attr_reader :ground
|
15
|
+
|
16
|
+
sig { params(ground: Symbol, values: T.any([Integer], [Integer, Integer, Integer])).returns(Color) }
|
17
|
+
def self.build(ground, values); end
|
18
|
+
|
19
|
+
sig { params(hex: String).returns([Integer, Integer, Integer]) }
|
20
|
+
def self.parse_hex_color(hex); end
|
21
|
+
|
22
|
+
class Indexed < Rainbow::Color
|
23
|
+
sig { returns(Integer) }
|
24
|
+
attr_reader :num
|
25
|
+
|
26
|
+
sig { params(ground: Symbol, num: Integer).void }
|
27
|
+
def initialize(ground, num); end
|
28
|
+
|
29
|
+
sig { returns(T::Array[Integer]) }
|
30
|
+
def codes; end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Named < Rainbow::Color::Indexed
|
34
|
+
NAMES = T.let(nil, T::Hash[Symbol, Integer])
|
35
|
+
|
36
|
+
sig { params(ground: Symbol, name: Symbol).void }
|
37
|
+
def initialize(ground, name); end
|
38
|
+
|
39
|
+
sig { returns(T::Array[Symbol]) }
|
40
|
+
def self.color_names; end
|
41
|
+
|
42
|
+
sig { returns(String) }
|
43
|
+
def self.valid_names; end
|
44
|
+
end
|
45
|
+
|
46
|
+
class RGB < Rainbow::Color::Indexed
|
47
|
+
sig { returns(Integer) }
|
48
|
+
attr_reader :r, :g, :b
|
49
|
+
|
50
|
+
sig { params(ground: Symbol, values: Integer).void }
|
51
|
+
def initialize(ground, *values); end
|
52
|
+
|
53
|
+
sig { returns(T::Array[Integer]) }
|
54
|
+
def codes; end
|
55
|
+
|
56
|
+
sig { params(value: Numeric).returns(Integer) }
|
57
|
+
def self.to_ansi_domain(value); end
|
58
|
+
end
|
59
|
+
|
60
|
+
class X11Named < Rainbow::Color::RGB
|
61
|
+
include Rainbow::X11ColorNames
|
62
|
+
|
63
|
+
sig { returns(T::Array[Symbol]) }
|
64
|
+
def self.color_names; end
|
65
|
+
|
66
|
+
sig { returns(String) }
|
67
|
+
def self.valid_names; end
|
68
|
+
|
69
|
+
sig { params(ground: Symbol, name: Symbol).void }
|
70
|
+
def initialize(ground, name); end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
sig { returns(Wrapper) }
|
75
|
+
def self.global; end
|
76
|
+
|
77
|
+
sig { returns(T::Boolean) }
|
78
|
+
def self.enabled; end
|
79
|
+
|
80
|
+
sig { params(value: T::Boolean).returns(T::Boolean) }
|
81
|
+
def self.enabled=(value); end
|
82
|
+
|
83
|
+
sig { params(string: String).returns(String) }
|
84
|
+
def self.uncolor(string); end
|
85
|
+
|
86
|
+
class NullPresenter < String
|
87
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
88
|
+
def color(*values); end
|
89
|
+
|
90
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
91
|
+
def foreground(*values); end
|
92
|
+
|
93
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
94
|
+
def fg(*values); end
|
95
|
+
|
96
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
97
|
+
def background(*values); end
|
98
|
+
|
99
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
100
|
+
def bg(*values); end
|
101
|
+
|
102
|
+
sig { returns(NullPresenter) }
|
103
|
+
def reset; end
|
104
|
+
|
105
|
+
sig { returns(NullPresenter) }
|
106
|
+
def bright; end
|
107
|
+
|
108
|
+
sig { returns(NullPresenter) }
|
109
|
+
def faint; end
|
110
|
+
|
111
|
+
sig { returns(NullPresenter) }
|
112
|
+
def italic; end
|
113
|
+
|
114
|
+
sig { returns(NullPresenter) }
|
115
|
+
def underline; end
|
116
|
+
|
117
|
+
sig { returns(NullPresenter) }
|
118
|
+
def blink; end
|
119
|
+
|
120
|
+
sig { returns(NullPresenter) }
|
121
|
+
def inverse; end
|
122
|
+
|
123
|
+
sig { returns(NullPresenter) }
|
124
|
+
def hide; end
|
125
|
+
|
126
|
+
sig { returns(NullPresenter) }
|
127
|
+
def cross_out; end
|
128
|
+
|
129
|
+
sig { returns(NullPresenter) }
|
130
|
+
def black; end
|
131
|
+
|
132
|
+
sig { returns(NullPresenter) }
|
133
|
+
def red; end
|
134
|
+
|
135
|
+
sig { returns(NullPresenter) }
|
136
|
+
def green; end
|
137
|
+
|
138
|
+
sig { returns(NullPresenter) }
|
139
|
+
def yellow; end
|
140
|
+
|
141
|
+
sig { returns(NullPresenter) }
|
142
|
+
def blue; end
|
143
|
+
|
144
|
+
sig { returns(NullPresenter) }
|
145
|
+
def magenta; end
|
146
|
+
|
147
|
+
sig { returns(NullPresenter) }
|
148
|
+
def cyan; end
|
149
|
+
|
150
|
+
sig { returns(NullPresenter) }
|
151
|
+
def white; end
|
152
|
+
|
153
|
+
sig { returns(NullPresenter) }
|
154
|
+
def bold; end
|
155
|
+
|
156
|
+
sig { returns(NullPresenter) }
|
157
|
+
def dark; end
|
158
|
+
|
159
|
+
sig { returns(NullPresenter) }
|
160
|
+
def strike; end
|
161
|
+
end
|
162
|
+
|
163
|
+
class Presenter < String
|
164
|
+
TERM_EFFECTS = T.let(nil, T::Hash[Symbol, Integer])
|
165
|
+
|
166
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
167
|
+
def color(*values); end
|
168
|
+
|
169
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
170
|
+
def foreground(*values); end
|
171
|
+
|
172
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
173
|
+
def fg(*values); end
|
174
|
+
|
175
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
176
|
+
def background(*values); end
|
177
|
+
|
178
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
179
|
+
def bg(*values); end
|
180
|
+
|
181
|
+
sig { returns(Presenter) }
|
182
|
+
def reset; end
|
183
|
+
|
184
|
+
sig { returns(Presenter) }
|
185
|
+
def bright; end
|
186
|
+
|
187
|
+
sig { returns(Presenter) }
|
188
|
+
def faint; end
|
189
|
+
|
190
|
+
sig { returns(Presenter) }
|
191
|
+
def italic; end
|
192
|
+
|
193
|
+
sig { returns(Presenter) }
|
194
|
+
def underline; end
|
195
|
+
|
196
|
+
sig { returns(Presenter) }
|
197
|
+
def blink; end
|
198
|
+
|
199
|
+
sig { returns(Presenter) }
|
200
|
+
def inverse; end
|
201
|
+
|
202
|
+
sig { returns(Presenter) }
|
203
|
+
def hide; end
|
204
|
+
|
205
|
+
sig { returns(Presenter) }
|
206
|
+
def cross_out; end
|
207
|
+
|
208
|
+
sig { returns(Presenter) }
|
209
|
+
def black; end
|
210
|
+
|
211
|
+
sig { returns(Presenter) }
|
212
|
+
def red; end
|
213
|
+
|
214
|
+
sig { returns(Presenter) }
|
215
|
+
def green; end
|
216
|
+
|
217
|
+
sig { returns(Presenter) }
|
218
|
+
def yellow; end
|
219
|
+
|
220
|
+
sig { returns(Presenter) }
|
221
|
+
def blue; end
|
222
|
+
|
223
|
+
sig { returns(Presenter) }
|
224
|
+
def magenta; end
|
225
|
+
|
226
|
+
sig { returns(Presenter) }
|
227
|
+
def cyan; end
|
228
|
+
|
229
|
+
sig { returns(Presenter) }
|
230
|
+
def white; end
|
231
|
+
|
232
|
+
sig { returns(Presenter) }
|
233
|
+
def bold; end
|
234
|
+
|
235
|
+
sig { returns(Presenter) }
|
236
|
+
def dark; end
|
237
|
+
|
238
|
+
sig { returns(Presenter) }
|
239
|
+
def strike; end
|
240
|
+
end
|
241
|
+
|
242
|
+
class StringUtils
|
243
|
+
sig { params(string: String, codes: T::Array[Integer]).returns(String) }
|
244
|
+
def self.wrap_with_sgr(string, codes); end
|
245
|
+
|
246
|
+
sig { params(string: String).returns(String) }
|
247
|
+
def self.uncolor(string); end
|
248
|
+
end
|
249
|
+
|
250
|
+
VERSION = T.let(nil, String)
|
251
|
+
|
252
|
+
class Wrapper
|
253
|
+
sig { returns(T::Boolean) }
|
254
|
+
attr_accessor :enabled
|
255
|
+
|
256
|
+
sig { params(enabled: T::Boolean).void }
|
257
|
+
def initialize(enabled = true); end
|
258
|
+
|
259
|
+
sig { params(string: String).returns(T.any(Rainbow::Presenter, Rainbow::NullPresenter)) }
|
260
|
+
def wrap(string); end
|
261
|
+
end
|
262
|
+
|
263
|
+
module X11ColorNames
|
264
|
+
NAMES = T.let(nil, T::Hash[Symbol, [Integer, Integer, Integer]])
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
sig { params(string: String).returns(Rainbow::Presenter) }
|
269
|
+
def Rainbow(string); end
|