data_model 0.3.0 → 0.5.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 (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b19c7734dd0562c0ef848b80626af66d08fbb9899b4110bf489ddb5d8920bb96
4
- data.tar.gz: 9292e0267765d965788f54a37d6846a123acd045506f7451412be625193fb3e6
3
+ metadata.gz: c330ccaea1eb4d6a39ae646d1bfc1adea6fcea63398c393ca9daea37ad6c9345
4
+ data.tar.gz: 9ca8082aa99dd38e6c9838d089201be698713a2af312492d9f8d5c6d0512dddb
5
5
  SHA512:
6
- metadata.gz: f151b11149b2c97e93773f5857a16914ee2c85a3b83074106832ae426f43467533b79423ef5b943e6bca9b109a9db699ff06f454dda3c434f3844969c26330a2
7
- data.tar.gz: 235d0c7e9f26539e997f394a449e4f0a6662cce55563aa49e29552289087bd619730d992e2f691733a730a3a4b04ae7577c84a5b5f80441b3ebcd91e633aeedf
6
+ metadata.gz: e0b248691f742a60fe78029b5793cd00afd383457f3cd16610a56bb096e2cb37db0ad7c1cb064ec9fef4ffd6750b07857f8f2f4d44db3c06cf57ab342d6759c2
7
+ data.tar.gz: c5438f427c94cf00c3f4f64ed4078c80211f705d2646ad6489dcf4ae4c34165fa420498755e2131b2c0185cd84a57c582c7bac77a489f01f4cfa4d23a4bd2297
data/.rubocop.yml CHANGED
@@ -3,11 +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
+
15
+ Metrics/ClassLength:
16
+ Enabled: false
17
+
12
18
  Lint/BooleanSymbol:
13
19
  Enabled: false
20
+
21
+ Lint/UnusedMethodArgument:
22
+ Enabled: false
@@ -0,0 +1,2 @@
1
+ /.*
2
+ !/.gitignore
@@ -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/.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,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- data_model (0.3.0)
5
- sorbet
4
+ data_model (0.4.0)
6
5
  zeitwerk
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
10
9
  specs:
10
+ activesupport (7.0.5)
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.6)
13
19
  diff-lcs (1.5.0)
14
20
  ffi (1.15.5)
21
+ fileutils (1.7.1)
15
22
  formatador (1.1.0)
16
23
  guard (2.18.0)
17
24
  formatador (>= 0.2.4)
@@ -25,10 +32,14 @@ GEM
25
32
  guard-rake (1.0.0)
26
33
  guard
27
34
  rake
35
+ i18n (1.13.0)
36
+ concurrent-ruby (~> 1.0)
28
37
  json (2.6.3)
38
+ language_server-protocol (3.17.0.3)
29
39
  listen (3.8.0)
30
40
  rb-fsevent (~> 0.10, >= 0.10.3)
31
41
  rb-inotify (~> 0.9, >= 0.9.10)
42
+ logger (1.5.3)
32
43
  lumberjack (1.2.8)
33
44
  method_source (1.0.0)
34
45
  minitest (5.18.0)
@@ -53,6 +64,7 @@ GEM
53
64
  parser (>= 2.6.4.0)
54
65
  sorbet-runtime (>= 0.5.9204)
55
66
  unparser
67
+ rbs (3.1.0)
56
68
  regexp_parser (2.8.0)
57
69
  rexml (3.2.5)
58
70
  rubocop (1.50.2)
@@ -68,6 +80,8 @@ GEM
68
80
  rubocop-ast (1.28.0)
69
81
  parser (>= 3.2.1.0)
70
82
  ruby-progressbar (1.13.0)
83
+ rufo (0.16.1)
84
+ securerandom (0.2.2)
71
85
  shellany (0.0.1)
72
86
  sorbet (0.5.10795)
73
87
  sorbet-static (= 0.5.10795)
@@ -80,6 +94,22 @@ GEM
80
94
  sorbet (>= 0.5.10187)
81
95
  sorbet-runtime (>= 0.5.9204)
82
96
  thor (>= 0.19.2)
97
+ steep (1.4.0)
98
+ activesupport (>= 5.1)
99
+ concurrent-ruby (>= 1.2.2)
100
+ csv (>= 3.0.9)
101
+ fileutils (>= 1.1.0)
102
+ json (>= 2.1.0)
103
+ language_server-protocol (>= 3.15, < 4.0)
104
+ listen (~> 3.0)
105
+ logger (>= 1.3.0)
106
+ parser (>= 3.1)
107
+ rainbow (>= 2.2.2, < 4.0)
108
+ rbs (>= 2.8.0)
109
+ securerandom (>= 0.1)
110
+ strscan (>= 1.0.0)
111
+ terminal-table (>= 2, < 4)
112
+ strscan (3.0.6)
83
113
  tapioca (0.11.5)
84
114
  bundler (>= 2.2.25)
85
115
  netrc (>= 0.11.0)
@@ -89,7 +119,11 @@ GEM
89
119
  spoom (~> 1.2.0, >= 1.2.0)
90
120
  thor (>= 1.2.0)
91
121
  yard-sorbet
122
+ terminal-table (3.0.2)
123
+ unicode-display_width (>= 1.1.1, < 3)
92
124
  thor (1.2.1)
125
+ tzinfo (2.0.6)
126
+ concurrent-ruby (~> 1.0)
93
127
  unicode-display_width (2.4.2)
94
128
  unparser (0.6.7)
95
129
  diff-lcs (~> 1.3)
@@ -110,7 +144,8 @@ DEPENDENCIES
110
144
  minitest
111
145
  rake
112
146
  rubocop
113
- sorbet-runtime
147
+ rufo
148
+ steep
114
149
  tapioca
115
150
 
116
151
  BUNDLED WITH
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"
@@ -43,7 +42,8 @@ Gem::Specification.new do |spec|
43
42
  spec.add_development_dependency "minitest"
44
43
  spec.add_development_dependency "rake"
45
44
  spec.add_development_dependency "rubocop"
46
- spec.add_development_dependency "sorbet-runtime"
45
+ spec.add_development_dependency "rufo"
46
+ spec.add_development_dependency "steep"
47
47
  spec.add_development_dependency "tapioca"
48
48
 
49
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))