data_model 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -2
  3. data/.shadowenv.d/.gitignore +2 -0
  4. data/.shadowenv.d/550-ruby.lisp +37 -0
  5. data/.solargraph.yml +22 -0
  6. data/Gemfile.lock +38 -3
  7. data/Rakefile +0 -6
  8. data/Steepfile +27 -0
  9. data/data_model.gemspec +2 -2
  10. data/lib/data_model/boolean.rb +0 -2
  11. data/lib/data_model/builtin/array.rb +32 -25
  12. data/lib/data_model/builtin/big_decimal.rb +15 -14
  13. data/lib/data_model/builtin/boolean.rb +10 -7
  14. data/lib/data_model/builtin/date.rb +15 -12
  15. data/lib/data_model/builtin/float.rb +14 -13
  16. data/lib/data_model/builtin/hash.rb +100 -35
  17. data/lib/data_model/builtin/integer.rb +14 -13
  18. data/lib/data_model/builtin/numeric.rb +35 -0
  19. data/lib/data_model/builtin/object.rb +28 -0
  20. data/lib/data_model/builtin/or.rb +73 -0
  21. data/lib/data_model/builtin/string.rb +15 -16
  22. data/lib/data_model/builtin/symbol.rb +14 -13
  23. data/lib/data_model/builtin/time.rb +17 -14
  24. data/lib/data_model/builtin.rb +9 -9
  25. data/lib/data_model/error.rb +33 -33
  26. data/lib/data_model/errors.rb +107 -143
  27. data/lib/data_model/fixtures/array.rb +22 -9
  28. data/lib/data_model/fixtures/big_decimal.rb +9 -7
  29. data/lib/data_model/fixtures/boolean.rb +5 -5
  30. data/lib/data_model/fixtures/date.rb +13 -11
  31. data/lib/data_model/fixtures/example.rb +7 -7
  32. data/lib/data_model/fixtures/float.rb +9 -7
  33. data/lib/data_model/fixtures/hash.rb +22 -10
  34. data/lib/data_model/fixtures/integer.rb +9 -7
  35. data/lib/data_model/fixtures/numeric.rb +31 -0
  36. data/lib/data_model/fixtures/object.rb +27 -0
  37. data/lib/data_model/fixtures/or.rb +29 -0
  38. data/lib/data_model/fixtures/string.rb +15 -32
  39. data/lib/data_model/fixtures/symbol.rb +9 -7
  40. data/lib/data_model/fixtures/time.rb +13 -11
  41. data/lib/data_model/logging.rb +5 -8
  42. data/lib/data_model/model.rb +11 -8
  43. data/lib/data_model/registry.rb +129 -0
  44. data/lib/data_model/scanner.rb +24 -29
  45. data/lib/data_model/struct.rb +112 -0
  46. data/lib/data_model/testing/minitest.rb +33 -9
  47. data/lib/data_model/testing.rb +0 -2
  48. data/lib/data_model/type.rb +39 -23
  49. data/lib/data_model/version.rb +1 -3
  50. data/lib/data_model.rb +10 -19
  51. metadata +24 -21
  52. data/lib/data_model/type_registry.rb +0 -68
  53. data/sorbet/config +0 -4
  54. data/sorbet/rbi/annotations/rainbow.rbi +0 -269
  55. data/sorbet/rbi/gems/minitest@5.18.0.rbi +0 -1491
  56. data/sorbet/rbi/gems/zeitwerk.rbi +0 -196
  57. data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +0 -966
  58. data/sorbet/rbi/todo.rbi +0 -5
  59. data/sorbet/tapioca/config.yml +0 -13
  60. data/sorbet/tapioca/require.rb +0 -4
@@ -1,26 +1,73 @@
1
- # typed: strict
2
-
3
1
  module DataModel
4
- # Hash type has a concept of "child types"
2
+ # Hash type has a concept of "child types". They can either be specified
3
+ # as params of nested child arrays, or in a hash notation if specific
4
+ # keys are not being specified
5
+ #
6
+ # This is by far the most complex built-in type
7
+ #
8
+ # Example:
9
+ # [:hash, [:name, :string], [:email, :string]] # must have two specific keys
10
+ # [:hash, [symbol: :string] # key and values must be according to type
11
+ # [:hash, [symbol: [:string, {optional: true}]]] # types can be specified long hand
5
12
  class Builtin::Hash < Type
6
13
  include Errors
7
14
  include Logging
8
15
 
9
- class Arguments < T::Struct
10
- prop :optional, T::Boolean, default: false
11
- prop :open, T::Boolean, default: true
16
+ class Arguments < Struct
17
+ prop :optional, :boolean, default: false
18
+ prop :open, :boolean, default: true
12
19
  end
13
20
 
14
21
  ## Children
15
22
 
16
- sig { override.params(params: T::Array[Object]).void }
23
+ # configure how hash children will be read
24
+ # @param params [Array] the params to configure
25
+ # @return [void]
17
26
  def configure(params)
18
- result = T.let({}, T::Hash[Symbol, Type])
19
- @children = T.let(result, T.nilable(T::Hash[Symbol, Type]))
20
-
27
+ result = @children = {}
28
+ @key_value = false
21
29
  log.debug("configuring hash children")
22
30
 
23
- for child in T.cast(params, T::Array[T::Array[Object]])
31
+ if params.length == 1 && params.first.length == 1 && params.first.first.is_a?(Hash)
32
+ @key_value = true
33
+ log.debug("configuring hash children with {key => value} notation")
34
+ params = params.first.first
35
+
36
+ if params.length != 1
37
+ raise "expected only one key in the {key => value} notation, got #{params.length} for #{params.inspect}"
38
+ end
39
+
40
+ key = params.keys.first
41
+ value = params.values.first
42
+
43
+ if key.nil?
44
+ raise "schema for key is missing"
45
+ end
46
+
47
+ if value.nil?
48
+ raise "schema for value is missing"
49
+ end
50
+
51
+ key_node = Scanner.scan(Array(key), type_registry)
52
+ value_node = Scanner.scan(Array(value), type_registry)
53
+
54
+ result[:key] = type_registry.type(
55
+ key_node.type,
56
+ args: key_node.args,
57
+ params: key_node.params,
58
+ )
59
+
60
+ result[:value] = type_registry.type(
61
+ value_node.type,
62
+ args: value_node.args,
63
+ params: value_node.params,
64
+ )
65
+
66
+ return
67
+ end
68
+
69
+ log.debug("configuring hash children with array notation")
70
+ for child in params
24
71
  name, *schema = child
25
72
  if !name.is_a?(Symbol)
26
73
  raise "expected name as a symbol for the first element of child schemas, got #{name.inspect} for #{child.inspect}"
@@ -31,13 +78,14 @@ module DataModel
31
78
  end
32
79
 
33
80
  node = Scanner.scan(schema)
34
- log.debug("adding hash child -> #{name}: #{node.serialize}")
81
+ log.debug("adding hash child -> #{name}: #{node.to_h}")
35
82
 
36
83
  result[name] = instantiate(node.type, args: node.args, params: node.params)
37
84
  end
38
85
  end
39
86
 
40
- sig { returns(T::Hash[Symbol, Type]) }
87
+ # get the children types of this hash
88
+ # @return [Hash] the children types of this hash
41
89
  def children
42
90
  if @children.nil?
43
91
  raise "children not configured"
@@ -48,7 +96,10 @@ module DataModel
48
96
 
49
97
  ## Read
50
98
 
51
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
99
+ # read a value, and validate it
100
+ # @param val [Object] the value to read
101
+ # @param coerce [Boolean] whether to coerce the value
102
+ # @return [Array(Object, Error)] the result of reading the value
52
103
  def read(val, coerce: false)
53
104
  args = Arguments.new(type_args)
54
105
  errors = Error.new
@@ -59,34 +110,32 @@ module DataModel
59
110
  end
60
111
 
61
112
  if !args.optional && val.nil?
62
- errors.add(missing_error(Hash))
113
+ errors.add(missing_error(type_name))
63
114
  return [val, errors]
64
115
  end
65
116
 
66
117
  # type error, early exit
67
118
  if !val.is_a?(Hash) && !coerce
68
- errors.add(type_error(Hash, val))
119
+ errors.add(type_error(type_name, val))
69
120
  return [val, errors]
70
121
  end
71
122
 
72
123
  # attempt coercion
73
124
  if !val.is_a?(Hash) && coerce
74
125
  if val.respond_to?(:to_h)
75
- val = T.unsafe(val).to_h
126
+ val = val.to_h
76
127
  elsif val.respond_to?(:to_hash)
77
128
  val = Hash(val)
78
129
  else
79
- errors.add(coerce_error(Hash, val))
130
+ errors.add(coerce_error(type_name, val))
80
131
  return [val, errors]
81
132
  end
82
133
  end
83
134
 
84
- hash = T.cast(val, T::Hash[Symbol, Object])
85
-
86
135
  # detect extra keys then what is defined in the schema
87
136
  if !args.open
88
137
  keys = children.keys
89
- extra = hash.keys - keys
138
+ extra = val.keys - keys
90
139
 
91
140
  if !extra.empty?
92
141
  errors.add(extra_keys_error(extra))
@@ -95,23 +144,39 @@ module DataModel
95
144
  end
96
145
 
97
146
  # process children
98
- log.debug("processing hash children")
99
- for (name, child) in children
100
- hash[name], child_errors = child.read(hash[name], coerce:)
101
- log.debug("child #{name} -> #{hash[name].inspect} #{child_errors.inspect}")
102
-
103
- if !child_errors.any?
104
- log.debug("no errors, skipping")
105
- next
147
+ if @key_value
148
+ log.debug("processing hash children with {key => value} notation")
149
+ key = children[:key]
150
+ value = children[:value]
151
+
152
+ for (k, v) in val.dup
153
+ log.debug("processing #{k} -> #{v.inspect}")
154
+ k, key_errors = key.read(k, coerce:)
155
+ v, value_errors = value.read(v, coerce:)
156
+
157
+ if !key_errors.any? && !value_errors.any?
158
+ log.debug("no errors")
159
+ val[k] = v
160
+ end
161
+
162
+ errors.merge_child(k, key_errors)
163
+ errors.merge_child(k, value_errors)
164
+ end
165
+ else
166
+ log.debug("processing hash children with array notation")
167
+ for (name, child) in children
168
+ val[name], child_errors = child.read(val[name], coerce:)
169
+ log.debug("child #{name} -> #{val[name].inspect} #{child_errors.inspect}")
170
+
171
+ if !child_errors.any?
172
+ log.debug("no errors, skipping")
173
+ next
174
+ end
175
+
176
+ errors.merge_child(name, child_errors)
106
177
  end
107
-
108
- errors.merge_child(name, child_errors)
109
-
110
- return [val, errors]
111
178
  end
112
179
 
113
- log.debug("hash check successful")
114
-
115
180
  # done
116
181
  return [val, errors]
117
182
  end
@@ -1,16 +1,19 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # Integer type
4
3
  class Builtin::Integer < Type
5
4
  include Errors
6
5
 
7
- class Arguments < T::Struct
8
- prop :optional, T::Boolean, default: false
9
- prop :min, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil
10
- prop :max, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil
6
+ # Arguments for Array type.
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
+ prop :min, :numeric, default: nil
10
+ prop :max, :numeric, default: nil
11
11
  end
12
12
 
13
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
13
+ # read a value, and validate it
14
+ # @param val [Object] the value to read
15
+ # @param coerce [Boolean] whether to coerce the value
16
+ # @return [Array(Object, Error)] the result of reading the value
14
17
  def read(val, coerce: false)
15
18
  err = Error.new
16
19
  args = Arguments.new(type_args)
@@ -20,12 +23,12 @@ module DataModel
20
23
  end
21
24
 
22
25
  if !args.optional && val.nil?
23
- err.add(missing_error(Integer))
26
+ err.add(missing_error(type_name))
24
27
  return [val, err]
25
28
  end
26
29
 
27
30
  if !val.is_a?(Integer) && !coerce
28
- err.add(type_error(Integer, val))
31
+ err.add(type_error(type_name, val))
29
32
  return [val, err]
30
33
  end
31
34
 
@@ -33,17 +36,15 @@ module DataModel
33
36
  if val.is_a?(String) || val.is_a?(Numeric)
34
37
  val = Integer(val)
35
38
  elsif val.respond_to?(:to_i)
36
- val = T.cast(T.unsafe(val).to_i, Integer)
39
+ val = val.to_i
37
40
  end
38
41
 
39
42
  if !val.is_a?(Integer)
40
- err.add(coerce_error(Integer, val))
43
+ err.add(coerce_error(type_name, val))
41
44
  return [val, err]
42
45
  end
43
46
  end
44
47
 
45
- val = T.cast(val, Integer)
46
-
47
48
  min = args.min
48
49
  if min && val <= min
49
50
  err.add(min_error(min, val))
@@ -0,0 +1,35 @@
1
+ module DataModel
2
+ # Numeric type is :integer | :float | :decimal
3
+ class Builtin::Numeric < Type
4
+ include Errors
5
+
6
+ # Arguments for this type
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
+ end
10
+
11
+ # read a value, and validate it
12
+ # @param val [Object] the value to read
13
+ # @param coerce [Boolean] whether to coerce the value
14
+ # @return [Array(Object, Error)] the result of reading the value
15
+ def read(val, coerce: false)
16
+ args = Arguments.new(type_args)
17
+ err = Error.new
18
+
19
+ # optional and missing
20
+ if !args.optional && val.nil?
21
+ err.add(missing_error(type_name))
22
+ end
23
+
24
+ # when missing, return early
25
+ if val.nil?
26
+ return [val, err]
27
+ end
28
+
29
+ val, err = invoke(:or, val, params: [:integer, :float, :decimal], coerce:)
30
+
31
+ # done
32
+ return [val, err]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ module DataModel
2
+ # acts as any type, the only way to fail validation is if it is nil and not present
3
+ class Builtin::Object < Type
4
+ include Errors
5
+
6
+ # Object arguments
7
+ class Arguments < Struct
8
+ # @!attribute optional
9
+ # @return [Boolean] whether or not this type is optional
10
+ prop :optional, :boolean, default: false
11
+ end
12
+
13
+ # read a value, and validate it
14
+ # @param val [Object] the value to read
15
+ # @param coerce [Boolean] whether to coerce the value
16
+ # @return [Array(Object, Error)] the result of reading the value
17
+ def read(val, coerce: false)
18
+ args = Arguments.new(type_args)
19
+ err = Error.new
20
+
21
+ if val.nil? && !args.optional
22
+ err.add(missing_error(type_name))
23
+ end
24
+
25
+ return [val, err]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,73 @@
1
+ module DataModel
2
+ # Or type, allows for value to be one of several types
3
+ # Types will be tried in order. The first type to succeed will be used.
4
+ # If all types fail, the or type fails
5
+ #
6
+ # @example
7
+ # [:or, :string, [:array, :string]]
8
+ class Builtin::Or < Type
9
+ include Errors
10
+ include Logging
11
+
12
+ # Arguments for this type
13
+ class Arguments < Struct
14
+ prop :optional, :boolean, default: false
15
+ end
16
+
17
+ # support either :string shorthand or [:string, {optional: true}]
18
+ # @param params [Array<untyped>] the params to configure this type
19
+ # @return [void]
20
+ def configure(params)
21
+ if params.first.is_a?(Array)
22
+ params = params.first
23
+ end
24
+
25
+ @child_types = []
26
+
27
+ nodes = params.map { |p| Scanner.scan(Array(p)) }
28
+ for node in nodes
29
+ type = instantiate(node.type, args: node.args, params: node.params)
30
+ @child_types << type
31
+ end
32
+ end
33
+
34
+ # read a value, and validate it
35
+ # @param val [Object] the value to read
36
+ # @param coerce [Boolean] whether to coerce the value
37
+ # @return [Array(Object, Error)] the result of reading the value
38
+ def read(val, coerce: false)
39
+ args = Arguments.new(type_args)
40
+ err = Error.new
41
+ child_names = @child_types.map(&:type_name)
42
+
43
+ log.debug("coerce: #{coerce} or type #{child_names} with value #{val}")
44
+
45
+ # optional and missing
46
+ if !args.optional && val.nil?
47
+ err.add(missing_error(child_names))
48
+ end
49
+
50
+ # when missing, return early
51
+ if val.nil?
52
+ return [val, err]
53
+ end
54
+
55
+ valid = false
56
+
57
+ for type in @child_types
58
+ val, err = type.read(val, coerce: coerce)
59
+ if err.empty?
60
+ valid = true
61
+ break
62
+ end
63
+ end
64
+
65
+ if !valid
66
+ err.add(type_error(child_names, val))
67
+ end
68
+
69
+ # done
70
+ return [val, err]
71
+ end
72
+ end
73
+ end
@@ -1,20 +1,21 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # Built-in type for String
4
3
  class Builtin::String < Type
5
4
  include Errors
6
5
 
7
- TFormatter = T.type_alias { T.proc.params(val: String).returns(T::Boolean) }
8
-
9
- class Arguments < T::Struct
10
- prop :optional, T::Boolean, default: false
11
- prop :allow_blank, T::Boolean, default: true
12
- prop :format, T.nilable(T.any(String, Regexp, TFormatter)), default: nil
13
- prop :included, T::Array[String], default: []
14
- prop :excluded, T::Array[String], default: []
6
+ # Arguments for this type
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
+ prop :allow_blank, :boolean, default: true
10
+ prop :format, :string, default: nil
11
+ prop :included, [:array, :string], default: []
12
+ prop :excluded, [:array, :string], default: []
15
13
  end
16
14
 
17
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
15
+ # read a value, and validate it
16
+ # @param val [Object] the value to read
17
+ # @param coerce [Boolean] whether to coerce the value
18
+ # @return [Array(Object, Error)] the result of reading the value
18
19
  def read(val, coerce: false)
19
20
  args = Arguments.new(type_args)
20
21
  err = Error.new
@@ -25,13 +26,13 @@ module DataModel
25
26
  end
26
27
 
27
28
  if !args.optional && val.nil?
28
- err.add(missing_error(String))
29
+ err.add(missing_error(type_name))
29
30
  return [val, err]
30
31
  end
31
32
 
32
33
  # type error
33
34
  if !val.is_a?(String) && !coerce
34
- err.add(type_error(String, val))
35
+ err.add(type_error(type_name, val))
35
36
  return [val, err]
36
37
  end
37
38
 
@@ -40,13 +41,11 @@ module DataModel
40
41
  begin
41
42
  val = String(val)
42
43
  rescue TypeError
43
- err.add(coerce_error(String, val))
44
+ err.add(coerce_error(type_name, val))
44
45
  return [val, err]
45
46
  end
46
47
  end
47
48
 
48
- val = T.cast(val, String)
49
-
50
49
  # format
51
50
  fmt = args.format
52
51
  if fmt
@@ -1,16 +1,19 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # Symbol type
4
3
  class Builtin::Symbol < Type
5
4
  include Errors
6
5
 
7
- class Arguments < T::Struct
8
- prop :optional, T::Boolean, default: false
9
- prop :included, T::Array[Symbol], default: []
10
- prop :excluded, T::Array[Symbol], default: []
6
+ # Arguments for this type
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
+ prop :included, [:array, :symbol], default: []
10
+ prop :excluded, [:array, :symbol], default: []
11
11
  end
12
12
 
13
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
13
+ # read a value, and validate it
14
+ # @param val [Object] the value to read
15
+ # @param coerce [Boolean] whether to coerce the value
16
+ # @return [Array(Object, Error)] the result of reading the value
14
17
  def read(val, coerce: false)
15
18
  args = Arguments.new(type_args)
16
19
  err = Error.new
@@ -21,13 +24,13 @@ module DataModel
21
24
  end
22
25
 
23
26
  if !args.optional && val.nil?
24
- err.add(missing_error(Symbol))
27
+ err.add(missing_error(type_name))
25
28
  return [val, err]
26
29
  end
27
30
 
28
31
  # type error
29
32
  if !val.is_a?(Symbol) && !coerce
30
- err.add(type_error(Symbol, val))
33
+ err.add(type_error(type_name, val))
31
34
  return [val, err]
32
35
  end
33
36
 
@@ -36,15 +39,13 @@ module DataModel
36
39
  if val.is_a?(String)
37
40
  val = val.intern
38
41
  elsif val.respond_to?(:to_sym)
39
- val = T.unsafe(val).to_sym
42
+ val = val.to_sym
40
43
  else
41
- err.add(coerce_error(Symbol, val))
44
+ err.add(coerce_error(type_name, val))
42
45
  return [val, err]
43
46
  end
44
47
  end
45
48
 
46
- val = T.cast(val, Symbol)
47
-
48
49
  # inclusion
49
50
  if args.included.any? && !args.included.include?(val)
50
51
  err.add(inclusion_error(args.included))
@@ -1,16 +1,19 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # A time type
4
3
  class Builtin::Time < Type
5
4
  include Errors
6
5
 
7
- class Arguments < T::Struct
8
- prop :optional, T::Boolean, default: false
9
- prop :earliest, T.nilable(::Time), default: nil
10
- prop :latest, T.nilable(::Time), default: nil
6
+ # Arguments for this type
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
+ prop :earliest, [:time, { optional: true }], default: nil
10
+ prop :latest, [:time, { optional: true }], default: nil
11
11
  end
12
12
 
13
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
13
+ # read a value, and validate it
14
+ # @param val [Object] the value to read
15
+ # @param coerce [Boolean] whether to coerce the value
16
+ # @return [Array(Object, Error)] the result of reading the value
14
17
  def read(val, coerce: false)
15
18
  args = Arguments.new(type_args)
16
19
  err = Error.new
@@ -22,7 +25,7 @@ module DataModel
22
25
 
23
26
  # missing, but not allowed, don't do any more checks
24
27
  if val.nil?
25
- err.add(missing_error(Time))
28
+ err.add(missing_error(type_name))
26
29
  return [val, err]
27
30
  end
28
31
 
@@ -31,26 +34,26 @@ module DataModel
31
34
  begin
32
35
  val = Time.parse(val)
33
36
  rescue ArgumentError
34
- err.add(type_error(Time, val))
37
+ err.add(type_error(type_name, val))
35
38
  return [val, err]
36
39
  end
37
40
  end
38
41
 
39
42
  # not a date, don't do any more checks
40
43
  if !val.is_a?(Time)
41
- err.add(type_error(Time, val))
44
+ err.add(type_error(type_name, val))
42
45
  return [val, err]
43
46
  end
44
47
 
45
48
  # date is before the earliest point allowed
46
- if args.earliest && (val < T.must(args.earliest))
47
- error = earliest_error(T.must(args.earliest), val)
49
+ if args.earliest && (val < args.earliest)
50
+ error = earliest_error(args.earliest, val)
48
51
  err.add(error)
49
52
  end
50
53
 
51
54
  # date is after the latest point allowed
52
- if args.latest && (val > T.must(args.latest))
53
- error = latest_error(T.must(args.latest), val)
55
+ if args.latest && (val > args.latest)
56
+ error = latest_error(args.latest, val)
54
57
  err.add(error)
55
58
  end
56
59
 
@@ -1,22 +1,22 @@
1
- # typed: strict
2
-
3
1
  module DataModel
4
2
  module Builtin
5
- extend T::Sig
6
-
7
- sig { returns(TTypeMap) }
3
+ # Hash of all builtin types, useful when instanciating a Registry
4
+ # @return [Hash{Symbol => Type}] the builtin types
8
5
  def self.types
9
6
  {
10
7
  hash: Builtin::Hash,
8
+ array: Builtin::Array,
9
+ or: Builtin::Or,
10
+ object: Builtin::Object,
11
+ boolean: Builtin::Boolean,
12
+ date: Builtin::Date,
13
+ time: Builtin::Time,
11
14
  string: Builtin::String,
12
15
  symbol: Builtin::Symbol,
13
16
  integer: Builtin::Integer,
14
17
  decimal: Builtin::BigDecimal,
15
18
  float: Builtin::Float,
16
- boolean: Builtin::Boolean,
17
- array: Builtin::Array,
18
- date: Builtin::Date,
19
- time: Builtin::Time
19
+ numeric: Builtin::Numeric
20
20
  }
21
21
  end
22
22
  end