data_model 0.3.0 → 0.4.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/.rubocop.yml +3 -0
- data/.shadowenv.d/.gitignore +2 -0
- data/.shadowenv.d/550-ruby.lisp +37 -0
- data/Gemfile.lock +2 -0
- data/data_model.gemspec +1 -0
- data/lib/data_model/error.rb +4 -16
- data/lib/data_model/errors.rb +30 -90
- data/lib/data_model/registry.rb +114 -0
- data/lib/data_model/scanner.rb +2 -2
- data/lib/data_model/type.rb +2 -2
- data/lib/data_model/version.rb +1 -1
- data/lib/data_model.rb +3 -3
- metadata +20 -4
- data/lib/data_model/type_registry.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77b4364d2dc4198264ace712d5cb9f74a52120a6e878345f122091b4f10ec355
|
4
|
+
data.tar.gz: b886dbf46aa42f0bbfc8364cce01f959f1e4fc37849f83f3b3d0cf88521e46fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57c5dbc66e6d50aae767bb6f8eb7d192bbbef1912737675bc2ff63efb3ada68f06bee62a4f291d3b47e962d59d104f103d47ac2ce76ff6e6723e3c4cee090167
|
7
|
+
data.tar.gz: db075c6e83530263ecd90396c989f2fffd52a2b434031102501f85464f1e8253dd5fd85ae99b4c1a82622d6f0e21b1fd5808f19809575e6db264cb70c91dbc3c
|
data/.rubocop.yml
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
(provide "ruby" "3.2.0")
|
2
|
+
|
3
|
+
; remove any existing ruby paths and environment variables
|
4
|
+
(when-let ((ruby-root (env/get "RUBY_ROOT")))
|
5
|
+
(env/remove-from-pathlist "PATH" (path-concat ruby-root "bin"))
|
6
|
+
(when-let ((gem-root (env/get "GEM_ROOT")))
|
7
|
+
(env/remove-from-pathlist "PATH" (path-concat gem-root "bin")))
|
8
|
+
(when-let ((gem-home (env/get "GEM_HOME")))
|
9
|
+
(env/remove-from-pathlist "PATH" (path-concat gem-home "bin"))))
|
10
|
+
|
11
|
+
(env/set "GEM_PATH" ())
|
12
|
+
(env/set "GEM_HOME" ())
|
13
|
+
(env/set "RUBYOPT" ())
|
14
|
+
|
15
|
+
; set base ruby environment
|
16
|
+
(let ((version "3.2.2")
|
17
|
+
(gem-version "3.2.0")
|
18
|
+
(ruby-home (path-concat (env/get "HOME") ".rubies" (concat "ruby-" version))))
|
19
|
+
(do
|
20
|
+
(env/set "RUBY_ROOT" ruby-home)
|
21
|
+
(env/prepend-to-pathlist "PATH" (path-concat ruby-home "bin"))
|
22
|
+
(env/set "RUBY_ENGINE" "ruby")
|
23
|
+
(env/set "RUBY_VERSION" version)
|
24
|
+
(env/set "GEM_ROOT" (path-concat ruby-home "lib" "ruby" "gems" gem-version))))
|
25
|
+
|
26
|
+
; set gem environment
|
27
|
+
(when-let ((gem-root (env/get "GEM_ROOT")))
|
28
|
+
(env/prepend-to-pathlist "GEM_PATH" gem-root)
|
29
|
+
(env/prepend-to-pathlist "PATH" (path-concat gem-root "bin")))
|
30
|
+
|
31
|
+
; handle local gem home
|
32
|
+
(let ((gem-home
|
33
|
+
(path-concat (env/get "HOME") ".gem" (env/get "RUBY_ENGINE") (env/get "RUBY_VERSION"))))
|
34
|
+
(do
|
35
|
+
(env/set "GEM_HOME" gem-home)
|
36
|
+
(env/prepend-to-pathlist "GEM_PATH" gem-home)
|
37
|
+
(env/prepend-to-pathlist "PATH" (path-concat gem-home "bin"))))
|
data/Gemfile.lock
CHANGED
@@ -68,6 +68,7 @@ GEM
|
|
68
68
|
rubocop-ast (1.28.0)
|
69
69
|
parser (>= 3.2.1.0)
|
70
70
|
ruby-progressbar (1.13.0)
|
71
|
+
rufo (0.16.1)
|
71
72
|
shellany (0.0.1)
|
72
73
|
sorbet (0.5.10795)
|
73
74
|
sorbet-static (= 0.5.10795)
|
@@ -110,6 +111,7 @@ DEPENDENCIES
|
|
110
111
|
minitest
|
111
112
|
rake
|
112
113
|
rubocop
|
114
|
+
rufo
|
113
115
|
sorbet-runtime
|
114
116
|
tapioca
|
115
117
|
|
data/data_model.gemspec
CHANGED
@@ -43,6 +43,7 @@ Gem::Specification.new do |spec|
|
|
43
43
|
spec.add_development_dependency "minitest"
|
44
44
|
spec.add_development_dependency "rake"
|
45
45
|
spec.add_development_dependency "rubocop"
|
46
|
+
spec.add_development_dependency "rufo"
|
46
47
|
spec.add_development_dependency "sorbet-runtime"
|
47
48
|
spec.add_development_dependency "tapioca"
|
48
49
|
|
data/lib/data_model/error.rb
CHANGED
@@ -4,6 +4,7 @@ module DataModel
|
|
4
4
|
# Error is a class that holds errors.
|
5
5
|
class Error
|
6
6
|
extend T::Sig
|
7
|
+
include Errors
|
7
8
|
|
8
9
|
TErrorList = T.type_alias { T::Array[TError] }
|
9
10
|
TErrorMap = T.type_alias { T::Hash[Symbol, TErrorList] }
|
@@ -86,22 +87,9 @@ module DataModel
|
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
|
-
sig { params(
|
90
|
-
def
|
91
|
-
|
92
|
-
key, context = error
|
93
|
-
error[1] = blk.call(context, key)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
sig { params(blk: T.proc.params(context: Object, type: Symbol).returns(Object)).void }
|
98
|
-
def transform_child_context(&blk)
|
99
|
-
for error_list in @children.values
|
100
|
-
for error in error_list
|
101
|
-
key, context = error
|
102
|
-
error[1] = blk.call(context, key)
|
103
|
-
end
|
104
|
-
end
|
90
|
+
sig { params(registry: Registry).returns(T::Hash[Symbol, T::Array[String]]) }
|
91
|
+
def to_messages(registry: Registry.instance)
|
92
|
+
return registry.error_messages(self)
|
105
93
|
end
|
106
94
|
end
|
107
95
|
end
|
data/lib/data_model/errors.rb
CHANGED
@@ -5,6 +5,7 @@ module DataModel
|
|
5
5
|
module Errors
|
6
6
|
include Kernel
|
7
7
|
extend T::Sig
|
8
|
+
extend self
|
8
9
|
|
9
10
|
TTemporal = T.type_alias { T.any(::Date, ::Time, ::DateTime) }
|
10
11
|
|
@@ -156,141 +157,80 @@ module DataModel
|
|
156
157
|
"value #{val} does not match format #{format}"
|
157
158
|
end
|
158
159
|
|
159
|
-
|
160
|
-
# TODO: split this file
|
160
|
+
# Builders
|
161
161
|
|
162
162
|
TErrorMessageBuilder = T.type_alias { T.proc.params(ctx: T.untyped).returns(String) }
|
163
|
-
|
164
|
-
# Register a custom error message for use with custom errors
|
165
|
-
sig { params(type: Symbol, block: TErrorMessageBuilder).void }
|
166
|
-
def register_error_message(type, &block)
|
167
|
-
error_message_builders[type] = block
|
168
|
-
end
|
169
|
-
|
170
163
|
TErrorMessages = T.type_alias { T::Hash[Symbol, TErrorMessageBuilder] }
|
171
164
|
TClassValueCtx = T.type_alias { [T.class_of(Object), Object] }
|
172
165
|
TClassCtx = T.type_alias { T.class_of(Object) }
|
173
166
|
TSetCtx = T.type_alias { T::Array[Symbol] }
|
174
167
|
TWithinCtx = T.type_alias { [Numeric, Numeric] }
|
175
|
-
TWithinTemporalCtx = T.type_alias { [TTemporal, TTemporal] }
|
168
|
+
TWithinTemporalCtx = T.type_alias { [Errors::TTemporal, Errors::TTemporal] }
|
176
169
|
TFormatCtx = T.type_alias { [Object, String] }
|
177
170
|
|
178
171
|
# Get the error message builders
|
179
172
|
sig { returns(TErrorMessages) }
|
180
|
-
def
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
# wire up defaults
|
185
|
-
|
186
|
-
register_error_message(:type) do |ctx|
|
173
|
+
def self.error_messages
|
174
|
+
return {
|
175
|
+
type: lambda do |ctx|
|
187
176
|
cls, val = T.let(ctx, TClassValueCtx)
|
188
177
|
type_error_message(cls, val)
|
189
|
-
end
|
178
|
+
end,
|
190
179
|
|
191
|
-
|
180
|
+
coerce: lambda do |ctx|
|
192
181
|
cls, val = T.let(ctx, TClassValueCtx)
|
193
|
-
|
194
|
-
end
|
182
|
+
type_error_message(cls, val)
|
183
|
+
end,
|
195
184
|
|
196
|
-
|
185
|
+
missing: lambda do |ctx|
|
197
186
|
cls = T.let(ctx, TClassCtx)
|
198
187
|
missing_error_message(cls)
|
199
|
-
end
|
188
|
+
end,
|
200
189
|
|
201
|
-
|
190
|
+
inclusion: lambda do |ctx|
|
202
191
|
set = T.let(ctx, TSetCtx)
|
203
192
|
inclusion_error_message(set)
|
204
|
-
end
|
193
|
+
end,
|
205
194
|
|
206
|
-
|
195
|
+
exclusion: lambda do |ctx|
|
207
196
|
set = T.let(ctx, TSetCtx)
|
208
197
|
exclusion_error_message(set)
|
209
|
-
end
|
198
|
+
end,
|
210
199
|
|
211
|
-
|
200
|
+
extra_keys: lambda do |ctx|
|
212
201
|
set = T.let(ctx, TSetCtx)
|
213
202
|
extra_keys_error_message(set)
|
214
|
-
end
|
203
|
+
end,
|
215
204
|
|
216
|
-
|
205
|
+
min: lambda do |ctx|
|
217
206
|
min, val = T.let(ctx, TWithinCtx)
|
218
207
|
min_error_message(min, val)
|
219
|
-
end
|
208
|
+
end,
|
220
209
|
|
221
|
-
|
210
|
+
max: lambda do |ctx|
|
222
211
|
max, val = T.let(ctx, TWithinCtx)
|
223
212
|
max_error_message(max, val)
|
224
|
-
end
|
213
|
+
end,
|
225
214
|
|
226
|
-
|
215
|
+
earliest: lambda do |ctx|
|
227
216
|
earliest, val = T.let(ctx, TWithinTemporalCtx)
|
228
217
|
early_error_message(earliest, val)
|
229
|
-
end
|
218
|
+
end,
|
230
219
|
|
231
|
-
|
220
|
+
latest: lambda do |ctx|
|
232
221
|
latest, val = T.let(ctx, TWithinTemporalCtx)
|
233
222
|
late_error_message(latest, val)
|
234
|
-
end
|
223
|
+
end,
|
235
224
|
|
236
|
-
|
225
|
+
blank: lambda do
|
237
226
|
blank_error_message
|
238
|
-
end
|
227
|
+
end,
|
239
228
|
|
240
|
-
|
229
|
+
format: lambda do |ctx|
|
241
230
|
format, val = T.let(ctx, TFormatCtx)
|
242
231
|
format_error_message(format, val)
|
243
232
|
end
|
244
|
-
|
245
|
-
|
246
|
-
@error_messages
|
247
|
-
end
|
248
|
-
|
249
|
-
# Build the error message for a given error
|
250
|
-
sig { params(error: TError).returns(String) }
|
251
|
-
def error_message(error)
|
252
|
-
type = T.let(error[0], Symbol)
|
253
|
-
ctx = T.let(error[1], T.untyped)
|
254
|
-
|
255
|
-
builder = error_message_builders[type]
|
256
|
-
|
257
|
-
if builder.nil?
|
258
|
-
raise "no error message builder for #{type}"
|
259
|
-
end
|
260
|
-
|
261
|
-
builder.call(ctx)
|
262
|
-
end
|
263
|
-
|
264
|
-
# TODO: separate builders from other use cases for this mixin
|
265
|
-
# Build error messages from error object
|
266
|
-
sig { params(error: Error).returns(T::Hash[Symbol, T::Array[String]]) }
|
267
|
-
def error_messages(error)
|
268
|
-
error.to_h.transform_values do |error_list|
|
269
|
-
error_list.map { |e| error_message(e) }
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
sig { params(error: Error, from: T.class_of(Object), to: T.class_of(Object)).void }
|
274
|
-
def set_error_class(error, from, to)
|
275
|
-
error.transform_context do |ctx, type|
|
276
|
-
case type
|
277
|
-
when :type, :coerce
|
278
|
-
cls, val = T.cast(ctx, TClassValueCtx)
|
279
|
-
if cls == from
|
280
|
-
[to, val]
|
281
|
-
else
|
282
|
-
[cls, val]
|
283
|
-
end
|
284
|
-
when :missing
|
285
|
-
if ctx == from
|
286
|
-
[to, val]
|
287
|
-
else
|
288
|
-
[cls, val]
|
289
|
-
end
|
290
|
-
else
|
291
|
-
[cls, val]
|
292
|
-
end
|
293
|
-
end
|
233
|
+
}
|
294
234
|
end
|
295
235
|
end
|
296
236
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module DataModel
|
4
|
+
# Registry 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 Registry
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
# Default types that will be used if alternative type map is not given
|
10
|
+
sig { returns(TTypeMap) }
|
11
|
+
def self.default_types
|
12
|
+
Builtin.types
|
13
|
+
end
|
14
|
+
|
15
|
+
sig { returns(Errors::TErrorMessages) }
|
16
|
+
def self.default_error_messages
|
17
|
+
Errors.error_messages
|
18
|
+
end
|
19
|
+
|
20
|
+
# Singleton instance that will be used globally unless instances given
|
21
|
+
sig { params(types: TTypeMap, errors: Errors::TErrorMessages).returns(Registry) }
|
22
|
+
def self.instance(types: default_types, errors: default_error_messages)
|
23
|
+
@instance ||= T.let(new(types:, errors:), T.nilable(Registry))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Register a type on the global instance
|
27
|
+
sig { params(name: Symbol, type: T.class_of(Type)).void }
|
28
|
+
def self.register(name, type)
|
29
|
+
instance.register(name, type)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Instanciate a new type registry. Default errors will always be used, but additional
|
33
|
+
# errors can be registered.
|
34
|
+
sig { params(types: TTypeMap, errors: Errors::TErrorMessages).void }
|
35
|
+
def initialize(types: self.class.default_types, errors: self.class.default_error_messages)
|
36
|
+
@error_messages = T.let(nil, T.nilable(Errors::TErrorMessages))
|
37
|
+
if errors
|
38
|
+
errors.each { |type, builder| register_error_message(type, &builder) }
|
39
|
+
end
|
40
|
+
|
41
|
+
@types = T.let({}, TTypeMap)
|
42
|
+
types.each { |(name, type)| register(name, type) }
|
43
|
+
end
|
44
|
+
|
45
|
+
# Register a type on this instance
|
46
|
+
sig { params(name: Symbol, type: T.class_of(Type)).void }
|
47
|
+
def register(name, type)
|
48
|
+
@types[name] = type
|
49
|
+
end
|
50
|
+
|
51
|
+
# Check if a type is registered
|
52
|
+
sig { params(name: Symbol).returns(T::Boolean) }
|
53
|
+
def type?(name)
|
54
|
+
@types.key?(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Access and configure registered type
|
58
|
+
sig { params(name: Symbol, args: Type::TArguments, params: T.nilable(T::Array[Object])).returns(Type) }
|
59
|
+
def type(name, args: {}, params: nil)
|
60
|
+
if !type?(name)
|
61
|
+
raise "#{name} is not registered as a type"
|
62
|
+
end
|
63
|
+
|
64
|
+
t = @types.fetch(name).new(args, registry: self)
|
65
|
+
|
66
|
+
if params
|
67
|
+
t.configure(params)
|
68
|
+
end
|
69
|
+
|
70
|
+
return t
|
71
|
+
end
|
72
|
+
|
73
|
+
## API
|
74
|
+
|
75
|
+
# Register a custom error message for use with custom errors
|
76
|
+
sig { params(type: Symbol, block: Errors::TErrorMessageBuilder).void }
|
77
|
+
def register_error_message(type, &block)
|
78
|
+
error_message_builders[type] = block
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get the error message builders
|
82
|
+
sig { returns(Errors::TErrorMessages) }
|
83
|
+
def error_message_builders
|
84
|
+
if @error_messages.nil?
|
85
|
+
@error_messages ||= T.let({}, T.nilable(Errors::TErrorMessages))
|
86
|
+
end
|
87
|
+
|
88
|
+
@error_messages
|
89
|
+
end
|
90
|
+
|
91
|
+
# Build the error message for a given error
|
92
|
+
sig { params(error: TError).returns(String) }
|
93
|
+
def error_message(error)
|
94
|
+
type = T.let(error[0], Symbol)
|
95
|
+
ctx = T.let(error[1], T.untyped)
|
96
|
+
|
97
|
+
builder = error_message_builders[type]
|
98
|
+
|
99
|
+
if builder.nil?
|
100
|
+
raise "no error message builder for #{type}"
|
101
|
+
end
|
102
|
+
|
103
|
+
builder.call(ctx)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Build error messages from error object
|
107
|
+
sig { params(error: Error).returns(T::Hash[Symbol, T::Array[String]]) }
|
108
|
+
def error_messages(error)
|
109
|
+
error.to_h.transform_values do |error_list|
|
110
|
+
error_list.map { |e| error_message(e) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/data_model/scanner.rb
CHANGED
@@ -32,8 +32,8 @@ module DataModel
|
|
32
32
|
|
33
33
|
# Scan a schema, which is defined as a data structure, into a struct that is easier to work with.
|
34
34
|
# "Syntax" validations will be enforced at this level.
|
35
|
-
sig { params(schema: TSchema, registry: DataModel::
|
36
|
-
def scan(schema, registry =
|
35
|
+
sig { params(schema: TSchema, registry: DataModel::Registry).returns(Node) }
|
36
|
+
def scan(schema, registry = Registry.instance)
|
37
37
|
# state:
|
38
38
|
# nil (start) -> :type (we have a type) -> :args (we have arguments)
|
39
39
|
scanned = Node.new
|
data/lib/data_model/type.rb
CHANGED
@@ -12,8 +12,8 @@ module DataModel
|
|
12
12
|
TTypeParams = T.type_alias { T::Array[Object] }
|
13
13
|
TTypeResult = T.type_alias { [Object, Error] }
|
14
14
|
|
15
|
-
sig { params(args: TArguments, registry:
|
16
|
-
def initialize(args, registry:
|
15
|
+
sig { params(args: TArguments, registry: Registry).void }
|
16
|
+
def initialize(args, registry: Registry.instance)
|
17
17
|
@type_args = args
|
18
18
|
@type_registry = registry
|
19
19
|
end
|
data/lib/data_model/version.rb
CHANGED
data/lib/data_model.rb
CHANGED
@@ -27,8 +27,8 @@ module DataModel
|
|
27
27
|
TTypeMap = T.type_alias { T::Hash[Symbol, T.class_of(Type)] }
|
28
28
|
|
29
29
|
# Scan a schema and create a data model, which is a configured type.
|
30
|
-
sig { params(schema: TSchema, registry:
|
31
|
-
def define(schema, registry:
|
30
|
+
sig { params(schema: TSchema, registry: Registry).returns(Model) }
|
31
|
+
def define(schema, registry: Registry.instance)
|
32
32
|
scanned = Scanner.scan(schema, registry)
|
33
33
|
|
34
34
|
type = registry.type(
|
@@ -44,6 +44,6 @@ module DataModel
|
|
44
44
|
|
45
45
|
sig { params(name: Symbol, type: T.class_of(Type)).void }
|
46
46
|
def register_global_type(name, type)
|
47
|
-
|
47
|
+
Registry.register(name, type)
|
48
48
|
end
|
49
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Briggs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rufo
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
126
|
name: sorbet-runtime
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,6 +160,8 @@ files:
|
|
146
160
|
- ".editorconfig"
|
147
161
|
- ".rubocop.yml"
|
148
162
|
- ".ruby-version"
|
163
|
+
- ".shadowenv.d/.gitignore"
|
164
|
+
- ".shadowenv.d/550-ruby.lisp"
|
149
165
|
- Gemfile
|
150
166
|
- Gemfile.lock
|
151
167
|
- Guardfile
|
@@ -179,11 +195,11 @@ files:
|
|
179
195
|
- lib/data_model/fixtures/time.rb
|
180
196
|
- lib/data_model/logging.rb
|
181
197
|
- lib/data_model/model.rb
|
198
|
+
- lib/data_model/registry.rb
|
182
199
|
- lib/data_model/scanner.rb
|
183
200
|
- lib/data_model/testing.rb
|
184
201
|
- lib/data_model/testing/minitest.rb
|
185
202
|
- lib/data_model/type.rb
|
186
|
-
- lib/data_model/type_registry.rb
|
187
203
|
- lib/data_model/version.rb
|
188
204
|
- sorbet/config
|
189
205
|
- sorbet/rbi/annotations/rainbow.rbi
|
@@ -217,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
233
|
- !ruby/object:Gem::Version
|
218
234
|
version: '0'
|
219
235
|
requirements: []
|
220
|
-
rubygems_version: 3.4.
|
236
|
+
rubygems_version: 3.4.10
|
221
237
|
signing_key:
|
222
238
|
specification_version: 4
|
223
239
|
summary: Define a model for your data
|
@@ -1,68 +0,0 @@
|
|
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
|