data_model 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -2
  3. data/.solargraph.yml +22 -0
  4. data/Gemfile.lock +71 -29
  5. data/Rakefile +0 -6
  6. data/Steepfile +27 -0
  7. data/data_model.gemspec +1 -2
  8. data/lib/data_model/boolean.rb +0 -2
  9. data/lib/data_model/builtin/array.rb +32 -25
  10. data/lib/data_model/builtin/big_decimal.rb +15 -14
  11. data/lib/data_model/builtin/boolean.rb +10 -7
  12. data/lib/data_model/builtin/date.rb +15 -12
  13. data/lib/data_model/builtin/float.rb +14 -13
  14. data/lib/data_model/builtin/hash.rb +109 -36
  15. data/lib/data_model/builtin/integer.rb +14 -13
  16. data/lib/data_model/builtin/numeric.rb +35 -0
  17. data/lib/data_model/builtin/object.rb +28 -0
  18. data/lib/data_model/builtin/or.rb +73 -0
  19. data/lib/data_model/builtin/string.rb +15 -16
  20. data/lib/data_model/builtin/symbol.rb +14 -13
  21. data/lib/data_model/builtin/time.rb +17 -14
  22. data/lib/data_model/builtin.rb +9 -9
  23. data/lib/data_model/error.rb +30 -18
  24. data/lib/data_model/errors.rb +79 -55
  25. data/lib/data_model/fixtures/array.rb +22 -9
  26. data/lib/data_model/fixtures/big_decimal.rb +9 -7
  27. data/lib/data_model/fixtures/boolean.rb +5 -5
  28. data/lib/data_model/fixtures/date.rb +13 -11
  29. data/lib/data_model/fixtures/example.rb +7 -7
  30. data/lib/data_model/fixtures/float.rb +9 -7
  31. data/lib/data_model/fixtures/hash.rb +22 -10
  32. data/lib/data_model/fixtures/integer.rb +9 -7
  33. data/lib/data_model/fixtures/numeric.rb +31 -0
  34. data/lib/data_model/fixtures/object.rb +27 -0
  35. data/lib/data_model/fixtures/or.rb +29 -0
  36. data/lib/data_model/fixtures/string.rb +15 -32
  37. data/lib/data_model/fixtures/symbol.rb +9 -7
  38. data/lib/data_model/fixtures/time.rb +13 -11
  39. data/lib/data_model/logging.rb +5 -8
  40. data/lib/data_model/model.rb +11 -8
  41. data/lib/data_model/registry.rb +37 -22
  42. data/lib/data_model/scanner.rb +23 -28
  43. data/lib/data_model/struct.rb +116 -0
  44. data/lib/data_model/testing/minitest.rb +33 -9
  45. data/lib/data_model/testing.rb +0 -2
  46. data/lib/data_model/type.rb +38 -22
  47. data/lib/data_model/version.rb +1 -3
  48. data/lib/data_model.rb +8 -17
  49. metadata +13 -26
  50. data/sorbet/config +0 -4
  51. data/sorbet/rbi/annotations/rainbow.rbi +0 -269
  52. data/sorbet/rbi/gems/minitest@5.18.0.rbi +0 -1491
  53. data/sorbet/rbi/gems/zeitwerk.rbi +0 -196
  54. data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +0 -966
  55. data/sorbet/rbi/todo.rbi +0 -5
  56. data/sorbet/tapioca/config.yml +0 -13
  57. data/sorbet/tapioca/require.rb +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77b4364d2dc4198264ace712d5cb9f74a52120a6e878345f122091b4f10ec355
4
- data.tar.gz: b886dbf46aa42f0bbfc8364cce01f959f1e4fc37849f83f3b3d0cf88521e46fa
3
+ metadata.gz: f3a30187193b436d7dd863a4b2fe28d8baf21428d6fd936cb67555e9792786a7
4
+ data.tar.gz: e44e496aaf29d7ecd8dfd5633aae5275bb67a1ecfb821f7a64137f9532c36cca
5
5
  SHA512:
6
- metadata.gz: 57c5dbc66e6d50aae767bb6f8eb7d192bbbef1912737675bc2ff63efb3ada68f06bee62a4f291d3b47e962d59d104f103d47ac2ce76ff6e6723e3c4cee090167
7
- data.tar.gz: db075c6e83530263ecd90396c989f2fffd52a2b434031102501f85464f1e8253dd5fd85ae99b4c1a82622d6f0e21b1fd5808f19809575e6db264cb70c91dbc3c
6
+ metadata.gz: 9fd5b20f3a87909ef221656b6b541413f1201759e08cc51af148fbd18037c0b54b0253e2e21f51adf4503d4b61d1dbe4e5a929a62310574964e9214875d772a8
7
+ data.tar.gz: 47c5090b016f7ac15162c74e62464da01b1a4c170ae52db0f28f63d71a7686f7acd3063624b8c2ec5813d76fa826af56a1b4649d85162d220877e8053ff63890
data/.rubocop.yml CHANGED
@@ -3,14 +3,20 @@ inherit_from: "https://raw.githubusercontent.com/mbriggs/configs/main/dotfiles/r
3
3
  AllCops:
4
4
  SuggestExtensions: false
5
5
  Exclude:
6
- - 'bin/**/*'
7
- - 'sorbet/**/*'
6
+ - "bin/**/*"
7
+ - "sorbet/**/*"
8
8
 
9
9
  Style/GlobalStdStream:
10
10
  Enabled: false
11
11
 
12
+ Style/HashSyntax:
13
+ Enabled: false
14
+
12
15
  Metrics/ClassLength:
13
16
  Enabled: false
14
17
 
15
18
  Lint/BooleanSymbol:
16
19
  Enabled: false
20
+
21
+ Lint/UnusedMethodArgument:
22
+ Enabled: false
data/.solargraph.yml ADDED
@@ -0,0 +1,22 @@
1
+ ---
2
+ include:
3
+ - "**/*.rb"
4
+ exclude:
5
+ - spec/**/*
6
+ - test/**/*
7
+ - vendor/**/*
8
+ - ".bundle/**/*"
9
+ require: []
10
+ domains: []
11
+ reporters:
12
+ - rubocop
13
+ - require_not_found
14
+ formatter:
15
+ rubocop:
16
+ cops: safe
17
+ except: []
18
+ only: []
19
+ extra_args: []
20
+ require_paths: []
21
+ plugins: []
22
+ max_files: 5000
data/Gemfile.lock CHANGED
@@ -1,17 +1,25 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- data_model (0.3.0)
5
- sorbet
4
+ data_model (0.5.0)
6
5
  zeitwerk
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
10
9
  specs:
10
+ activesupport (7.0.6)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 1.6, < 2)
13
+ minitest (>= 5.1)
14
+ tzinfo (~> 2.0)
11
15
  ast (2.4.2)
12
16
  coderay (1.1.3)
17
+ concurrent-ruby (1.2.2)
18
+ csv (3.2.7)
13
19
  diff-lcs (1.5.0)
20
+ erubi (1.12.0)
14
21
  ffi (1.15.5)
22
+ fileutils (1.7.1)
15
23
  formatador (1.1.0)
16
24
  guard (2.18.0)
17
25
  formatador (>= 0.2.4)
@@ -25,63 +33,93 @@ GEM
25
33
  guard-rake (1.0.0)
26
34
  guard
27
35
  rake
36
+ i18n (1.14.1)
37
+ concurrent-ruby (~> 1.0)
28
38
  json (2.6.3)
39
+ language_server-protocol (3.17.0.3)
29
40
  listen (3.8.0)
30
41
  rb-fsevent (~> 0.10, >= 0.10.3)
31
42
  rb-inotify (~> 0.9, >= 0.9.10)
32
- lumberjack (1.2.8)
43
+ logger (1.5.3)
44
+ lumberjack (1.2.9)
33
45
  method_source (1.0.0)
34
- minitest (5.18.0)
46
+ minitest (5.19.0)
35
47
  nenv (0.3.0)
36
48
  netrc (0.11.0)
37
49
  notiffany (0.1.3)
38
50
  nenv (~> 0.1)
39
51
  shellany (~> 0.0)
40
52
  parallel (1.23.0)
41
- parser (3.2.2.1)
53
+ parser (3.2.2.3)
42
54
  ast (~> 2.4.1)
55
+ racc
56
+ prettier_print (1.2.1)
43
57
  pry (0.14.2)
44
58
  coderay (~> 1.1)
45
59
  method_source (~> 1.0)
60
+ racc (1.7.1)
46
61
  rainbow (3.1.1)
47
62
  rake (13.0.6)
48
63
  rb-fsevent (0.11.2)
49
64
  rb-inotify (0.10.1)
50
65
  ffi (~> 1.0)
51
- rbi (0.0.16)
66
+ rbi (0.0.17)
52
67
  ast
53
- parser (>= 2.6.4.0)
68
+ parser (>= 3.0.0)
54
69
  sorbet-runtime (>= 0.5.9204)
55
- unparser
56
- regexp_parser (2.8.0)
57
- rexml (3.2.5)
58
- rubocop (1.50.2)
70
+ unparser (>= 0.5.6)
71
+ rbs (3.1.3)
72
+ regexp_parser (2.8.1)
73
+ rexml (3.2.6)
74
+ rubocop (1.55.1)
59
75
  json (~> 2.3)
76
+ language_server-protocol (>= 3.17.0)
60
77
  parallel (~> 1.10)
61
- parser (>= 3.2.0.0)
78
+ parser (>= 3.2.2.3)
62
79
  rainbow (>= 2.2.2, < 4.0)
63
80
  regexp_parser (>= 1.8, < 3.0)
64
81
  rexml (>= 3.2.5, < 4.0)
65
- rubocop-ast (>= 1.28.0, < 2.0)
82
+ rubocop-ast (>= 1.28.1, < 2.0)
66
83
  ruby-progressbar (~> 1.7)
67
84
  unicode-display_width (>= 2.4.0, < 3.0)
68
- rubocop-ast (1.28.0)
85
+ rubocop-ast (1.29.0)
69
86
  parser (>= 3.2.1.0)
70
87
  ruby-progressbar (1.13.0)
71
- rufo (0.16.1)
88
+ rufo (0.16.2)
89
+ securerandom (0.2.2)
72
90
  shellany (0.0.1)
73
- sorbet (0.5.10795)
74
- sorbet-static (= 0.5.10795)
75
- sorbet-runtime (0.5.10795)
76
- sorbet-static (0.5.10795-universal-darwin-22)
77
- sorbet-static-and-runtime (0.5.10795)
78
- sorbet (= 0.5.10795)
79
- sorbet-runtime (= 0.5.10795)
80
- spoom (1.2.1)
91
+ sorbet (0.5.10950)
92
+ sorbet-static (= 0.5.10950)
93
+ sorbet-runtime (0.5.10950)
94
+ sorbet-static (0.5.10950-universal-darwin-22)
95
+ sorbet-static-and-runtime (0.5.10950)
96
+ sorbet (= 0.5.10950)
97
+ sorbet-runtime (= 0.5.10950)
98
+ spoom (1.2.2)
99
+ erubi (>= 1.10.0)
81
100
  sorbet (>= 0.5.10187)
82
101
  sorbet-runtime (>= 0.5.9204)
102
+ syntax_tree (>= 6.1.1)
83
103
  thor (>= 0.19.2)
84
- tapioca (0.11.5)
104
+ steep (1.5.2)
105
+ activesupport (>= 5.1)
106
+ concurrent-ruby (>= 1.1.10)
107
+ csv (>= 3.0.9)
108
+ fileutils (>= 1.1.0)
109
+ json (>= 2.1.0)
110
+ language_server-protocol (>= 3.15, < 4.0)
111
+ listen (~> 3.0)
112
+ logger (>= 1.3.0)
113
+ parser (>= 3.1)
114
+ rainbow (>= 2.2.2, < 4.0)
115
+ rbs (>= 3.1.0)
116
+ securerandom (>= 0.1)
117
+ strscan (>= 1.0.0)
118
+ terminal-table (>= 2, < 4)
119
+ strscan (3.0.6)
120
+ syntax_tree (6.1.1)
121
+ prettier_print (>= 1.2.0)
122
+ tapioca (0.11.8)
85
123
  bundler (>= 2.2.25)
86
124
  netrc (>= 0.11.0)
87
125
  parallel (>= 1.21.0)
@@ -90,16 +128,20 @@ GEM
90
128
  spoom (~> 1.2.0, >= 1.2.0)
91
129
  thor (>= 1.2.0)
92
130
  yard-sorbet
93
- thor (1.2.1)
131
+ terminal-table (3.0.2)
132
+ unicode-display_width (>= 1.1.1, < 3)
133
+ thor (1.2.2)
134
+ tzinfo (2.0.6)
135
+ concurrent-ruby (~> 1.0)
94
136
  unicode-display_width (2.4.2)
95
- unparser (0.6.7)
137
+ unparser (0.6.8)
96
138
  diff-lcs (~> 1.3)
97
139
  parser (>= 3.2.0)
98
140
  yard (0.9.34)
99
141
  yard-sorbet (0.8.1)
100
142
  sorbet-runtime (>= 0.5)
101
143
  yard (>= 0.9)
102
- zeitwerk (2.6.7)
144
+ zeitwerk (2.6.11)
103
145
 
104
146
  PLATFORMS
105
147
  arm64-darwin-22
@@ -112,8 +154,8 @@ DEPENDENCIES
112
154
  rake
113
155
  rubocop
114
156
  rufo
115
- sorbet-runtime
157
+ steep
116
158
  tapioca
117
159
 
118
160
  BUNDLED WITH
119
- 2.4.12
161
+ 2.4.18
data/Rakefile CHANGED
@@ -2,10 +2,6 @@
2
2
 
3
3
  require "minitest/test_task"
4
4
 
5
- Minitest::TestTask.create # named test, sensible defaults
6
-
7
- # or more explicitly:
8
-
9
5
  Minitest::TestTask.create(:test) do |t|
10
6
  t.libs << "test"
11
7
  t.libs << "lib"
@@ -13,8 +9,6 @@ Minitest::TestTask.create(:test) do |t|
13
9
  t.test_globs = ["test/**/*_test.rb"]
14
10
  end
15
11
 
16
- task default: :test
17
-
18
12
  require "rubocop/rake_task"
19
13
  RuboCop::RakeTask.new
20
14
 
data/Steepfile ADDED
@@ -0,0 +1,27 @@
1
+ # D = Steep::Diagnostic
2
+ #
3
+ # target :lib do
4
+ # signature "sig"
5
+ #
6
+ # check "lib" # Directory name
7
+ # check "Gemfile" # File name
8
+ # check "app/models/**/*.rb" # Glob
9
+ # # ignore "lib/templates/*.rb"
10
+ #
11
+ # # library "pathname", "set" # Standard libraries
12
+ # # library "strong_json" # Gems
13
+ #
14
+ # # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
15
+ # # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
16
+ # # configure_code_diagnostics do |hash| # You can setup everything yourself
17
+ # # hash[D::Ruby::NoMethod] = :information
18
+ # # end
19
+ # end
20
+
21
+ # target :test do
22
+ # signature "sig", "sig-private"
23
+ #
24
+ # check "test"
25
+ #
26
+ # # library "pathname", "set" # Standard libraries
27
+ # end
data/data_model.gemspec CHANGED
@@ -35,7 +35,6 @@ Gem::Specification.new do |spec|
35
35
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
36
36
  spec.require_paths = ["lib"]
37
37
 
38
- spec.add_dependency "sorbet"
39
38
  spec.add_dependency "zeitwerk"
40
39
 
41
40
  spec.add_development_dependency "guard"
@@ -44,7 +43,7 @@ Gem::Specification.new do |spec|
44
43
  spec.add_development_dependency "rake"
45
44
  spec.add_development_dependency "rubocop"
46
45
  spec.add_development_dependency "rufo"
47
- spec.add_development_dependency "sorbet-runtime"
46
+ spec.add_development_dependency "steep"
48
47
  spec.add_development_dependency "tapioca"
49
48
 
50
49
  # For more information and examples about making a new gem, check out our
@@ -1,5 +1,3 @@
1
- # typed: strict
2
-
3
1
  module DataModel
4
2
  # fills in for lack of boolean type in ruby
5
3
  class Boolean
@@ -1,47 +1,49 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # Array is a type that contains a list of other types.
3
+ #
4
+ # @example
5
+ # [:array, :string] # shorthand
6
+ # [:array, [:string, {optional: true}]]
4
7
  class Builtin::Array < Type
5
8
  include Errors
6
9
 
7
- class Arguments < T::Struct
8
- prop :optional, T::Boolean, default: false
9
- prop :wrap_single_value, T::Boolean, default: false
10
- prop :min, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil
11
- prop :max, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil
12
- prop :length, T.nilable(T.any(Integer, Float, Rational, BigDecimal)), default: nil
10
+ # Arguments for Array type.
11
+ class Arguments < Struct
12
+ prop :optional, :boolean, default: false
13
+ prop :wrap_single_value, :boolean, default: false
14
+ prop :min, :integer, default: nil
15
+ prop :max, :integer, default: nil
16
+ prop :length, :integer, default: nil
13
17
  end
14
18
 
15
- # support either :string shorthand or [:string, {optional: true}]
16
- sig { override.params(params: T::Array[Object]).void }
19
+ # get the child Type
20
+ # @return [Type] the child type
21
+ attr_reader :child_type
22
+
23
+ # configure how children will be read
24
+ # @param params [Array] the params to configure
25
+ # @return [void]
17
26
  def configure(params)
18
27
  if params.first.is_a?(Array)
19
28
  params = params.first
20
29
  end
21
30
 
22
- params = T.cast(params, TSchema)
23
31
  node = Scanner.scan(params)
24
32
  type = instantiate(node.type, args: node.args, params: node.params)
25
33
 
26
- @child_type = T.let(type, T.nilable(Type))
34
+ @child_type = type
27
35
  end
28
36
 
29
- sig { returns(Type) }
30
- def child_type
31
- if @child_type.nil?
32
- raise "children not configured"
33
- end
34
-
35
- return @child_type
36
- end
37
-
38
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
37
+ # read a value, and validate it
38
+ # @param val [Object] the value to read
39
+ # @param coerce [Boolean] whether to coerce the value
40
+ # @return [Array(Object, Error)] the result of reading the value
39
41
  def read(val, coerce: false)
40
42
  args = Arguments.new(type_args)
41
43
  err = Error.new
42
44
 
43
45
  if val.nil? && !args.optional
44
- err.add(missing_error(Array))
46
+ err.add(missing_error(type_name))
45
47
  return [val, err]
46
48
  end
47
49
 
@@ -50,14 +52,19 @@ module DataModel
50
52
  end
51
53
 
52
54
  if !val.is_a?(Array)
53
- err.add(type_error(Array, val))
55
+ err.add(type_error(type_name, val))
56
+ return [val, err]
57
+ end
58
+
59
+ # no child type configured, allow any array
60
+ if child_type.nil?
54
61
  return [val, err]
55
62
  end
56
63
 
57
64
  coerced = []
58
65
 
59
66
  for i in 0...val.length
60
- child_val = T.let(val[i], Object)
67
+ child_val = val[i]
61
68
  child, child_err = child_type.read(child_val, coerce:)
62
69
  if child_err
63
70
  err.merge_child(i.to_s.to_sym, child_err)
@@ -1,16 +1,19 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # A BigDecimal type.
4
3
  class Builtin::BigDecimal < 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 BigDecimal 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,30 +23,28 @@ module DataModel
20
23
  end
21
24
 
22
25
  if !args.optional && val.nil?
23
- err.add(missing_error(BigDecimal))
26
+ err.add(missing_error(type_name))
24
27
  return [val, err]
25
28
  end
26
29
 
27
30
  if !val.is_a?(BigDecimal) && !coerce
28
- err.add(type_error(BigDecimal, val))
31
+ err.add(type_error(type_name, val))
29
32
  return [val, err]
30
33
  end
31
34
 
32
35
  if !val.is_a?(BigDecimal) && coerce
33
36
  if val.is_a?(String) || val.is_a?(Numeric)
34
- val = BigDecimal(T.unsafe(val))
37
+ val = BigDecimal(val)
35
38
  elsif val.respond_to?(:to_d)
36
- val = T.cast(T.unsafe(val).to_d, BigDecimal)
39
+ val = val.to_d
37
40
  end
38
41
 
39
42
  if !val.is_a?(BigDecimal)
40
- err.add(coerce_error(BigDecimal, 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, BigDecimal)
46
-
47
48
  min = args.min
48
49
  if min && val <= min
49
50
  err.add(min_error(min, val))
@@ -1,19 +1,22 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # Boolean type
4
3
  class Builtin::Boolean < Type
5
4
  include Errors
6
5
 
7
- class Arguments < T::Struct
8
- prop :optional, T::Boolean, default: false
6
+ # Arguments for the boolean type
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
9
  end
10
10
 
11
- sig { override.params(val: Object, coerce: T::Boolean).returns(TTypeResult) }
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
12
15
  def read(val, coerce: false)
13
16
  err = Error.new
14
17
 
15
18
  if val.nil?
16
- err.add(missing_error(DataModel::Boolean))
19
+ err.add(missing_error(type_name))
17
20
  return [val, err]
18
21
  end
19
22
 
@@ -27,7 +30,7 @@ module DataModel
27
30
  end
28
31
 
29
32
  if !val.is_a?(TrueClass) && !val.is_a?(FalseClass)
30
- err.add(type_error(Boolean, val))
33
+ err.add(type_error(type_name, val))
31
34
  return [val, err]
32
35
  end
33
36
 
@@ -1,16 +1,19 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # A date type
4
3
  class Builtin::Date < Type
5
4
  include Errors
6
5
 
7
- class Arguments < T::Struct
8
- prop :optional, T::Boolean, default: false
9
- prop :earliest, T.nilable(::Date), default: nil
10
- prop :latest, T.nilable(::Date), default: nil
6
+ # Arguments for the date type
7
+ class Arguments < Struct
8
+ prop :optional, :boolean, default: false
9
+ prop :earliest, [:date, { optional: true }], default: nil
10
+ prop :latest, [:date, { 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(Date))
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 = Date.parse(val)
33
36
  rescue ArgumentError
34
- err.add(type_error(Date, 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?(Date)
41
- err.add(type_error(Date, 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
49
  if args.earliest && (val < args.earliest)
47
- error = earliest_error(T.must(args.earliest), val)
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
55
  if args.latest && (val > args.latest)
53
- error = latest_error(T.must(args.latest), val)
56
+ error = latest_error(args.latest, val)
54
57
  err.add(error)
55
58
  end
56
59
 
@@ -1,16 +1,19 @@
1
- # typed: strict
2
-
3
1
  module DataModel
2
+ # A float type.
4
3
  class Builtin::Float < 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 the float 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(Float))
26
+ err.add(missing_error(type_name))
24
27
  return [val, err]
25
28
  end
26
29
 
27
30
  if !val.is_a?(Float) && !coerce
28
- err.add(type_error(Float, 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 = Float(val)
35
38
  elsif val.respond_to?(:to_f)
36
- val = T.cast(T.unsafe(val).to_f, Float)
39
+ val = val.to_f
37
40
  end
38
41
 
39
42
  if !val.is_a?(Float)
40
- err.add(coerce_error(Float, 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, Float)
46
-
47
48
  min = args.min
48
49
  if min && val <= min
49
50
  err.add(min_error(min, val))