data_model 0.4.0 → 0.6.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.
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))