data_model 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +6 -2
  3. data/.rubocop.yml +11 -2
  4. data/.ruby-version +2 -0
  5. data/Gemfile.lock +91 -54
  6. data/Guardfile +20 -0
  7. data/Rakefile +32 -0
  8. data/data_model.gemspec +52 -0
  9. data/lib/data_model/boolean.rb +7 -0
  10. data/lib/data_model/builtin/array.rb +73 -0
  11. data/lib/data_model/builtin/big_decimal.rb +64 -0
  12. data/lib/data_model/builtin/boolean.rb +37 -0
  13. data/lib/data_model/builtin/date.rb +60 -0
  14. data/lib/data_model/builtin/float.rb +64 -0
  15. data/lib/data_model/builtin/hash.rb +119 -0
  16. data/lib/data_model/builtin/integer.rb +64 -0
  17. data/lib/data_model/builtin/string.rb +88 -0
  18. data/lib/data_model/builtin/symbol.rb +64 -0
  19. data/lib/data_model/builtin/time.rb +60 -0
  20. data/lib/data_model/builtin.rb +23 -0
  21. data/lib/data_model/error.rb +107 -0
  22. data/lib/data_model/errors.rb +296 -0
  23. data/lib/data_model/fixtures/array.rb +61 -0
  24. data/lib/data_model/fixtures/big_decimal.rb +55 -0
  25. data/lib/data_model/fixtures/boolean.rb +35 -0
  26. data/lib/data_model/fixtures/date.rb +53 -0
  27. data/lib/data_model/fixtures/example.rb +29 -0
  28. data/lib/data_model/fixtures/float.rb +53 -0
  29. data/lib/data_model/fixtures/hash.rb +66 -0
  30. data/lib/data_model/fixtures/integer.rb +53 -0
  31. data/lib/data_model/fixtures/string.rb +110 -0
  32. data/lib/data_model/fixtures/symbol.rb +56 -0
  33. data/lib/data_model/fixtures/time.rb +53 -0
  34. data/lib/data_model/logging.rb +23 -0
  35. data/lib/data_model/model.rb +21 -44
  36. data/lib/data_model/scanner.rb +92 -56
  37. data/lib/data_model/testing/minitest.rb +79 -0
  38. data/lib/data_model/testing.rb +6 -0
  39. data/lib/data_model/type.rb +41 -39
  40. data/lib/data_model/type_registry.rb +68 -0
  41. data/lib/data_model/version.rb +3 -1
  42. data/lib/data_model.rb +32 -16
  43. data/sorbet/config +4 -0
  44. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  45. data/sorbet/rbi/gems/minitest@5.18.0.rbi +1491 -0
  46. data/sorbet/rbi/gems/zeitwerk.rbi +196 -0
  47. data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +966 -0
  48. data/sorbet/rbi/todo.rbi +5 -0
  49. data/sorbet/tapioca/config.yml +13 -0
  50. data/sorbet/tapioca/require.rb +4 -0
  51. metadata +139 -17
  52. data/config/sus.rb +0 -2
  53. data/fixtures/schema.rb +0 -14
  54. 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
@@ -1,3 +1,5 @@
1
+ # typed: strict
2
+
1
3
  module DataModel
2
- VERSION = "0.0.1"
4
+ VERSION = "0.2.0"
3
5
  end
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
- def validate(schema, data, registry: Registry.instance)
10
- _, err = read(schema, data, registry:)
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
- def read(schema, data, registry: Registry.instance)
15
- Model.read(compiled(schema, registry:), data)
16
- end
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
- def write(schema, data, registry: Registry.instance)
19
- Model.write(compiled(schema, registry:), data)
20
- end
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
- def compiled(model, registry: Registry.instance)
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,4 @@
1
+ --dir
2
+ .
3
+ --ignore=/tmp/
4
+ --ignore=/vendor/bundle
@@ -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