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.
- checksums.yaml +4 -4
- data/.rubocop.yml +11 -2
- data/.shadowenv.d/.gitignore +2 -0
- data/.shadowenv.d/550-ruby.lisp +37 -0
- data/.solargraph.yml +22 -0
- data/Gemfile.lock +38 -3
- data/Rakefile +0 -6
- data/Steepfile +27 -0
- data/data_model.gemspec +2 -2
- data/lib/data_model/boolean.rb +0 -2
- data/lib/data_model/builtin/array.rb +32 -25
- data/lib/data_model/builtin/big_decimal.rb +15 -14
- data/lib/data_model/builtin/boolean.rb +10 -7
- data/lib/data_model/builtin/date.rb +15 -12
- data/lib/data_model/builtin/float.rb +14 -13
- data/lib/data_model/builtin/hash.rb +100 -35
- data/lib/data_model/builtin/integer.rb +14 -13
- data/lib/data_model/builtin/numeric.rb +35 -0
- data/lib/data_model/builtin/object.rb +28 -0
- data/lib/data_model/builtin/or.rb +73 -0
- data/lib/data_model/builtin/string.rb +15 -16
- data/lib/data_model/builtin/symbol.rb +14 -13
- data/lib/data_model/builtin/time.rb +17 -14
- data/lib/data_model/builtin.rb +9 -9
- data/lib/data_model/error.rb +33 -33
- data/lib/data_model/errors.rb +107 -143
- data/lib/data_model/fixtures/array.rb +22 -9
- data/lib/data_model/fixtures/big_decimal.rb +9 -7
- data/lib/data_model/fixtures/boolean.rb +5 -5
- data/lib/data_model/fixtures/date.rb +13 -11
- data/lib/data_model/fixtures/example.rb +7 -7
- data/lib/data_model/fixtures/float.rb +9 -7
- data/lib/data_model/fixtures/hash.rb +22 -10
- data/lib/data_model/fixtures/integer.rb +9 -7
- data/lib/data_model/fixtures/numeric.rb +31 -0
- data/lib/data_model/fixtures/object.rb +27 -0
- data/lib/data_model/fixtures/or.rb +29 -0
- data/lib/data_model/fixtures/string.rb +15 -32
- data/lib/data_model/fixtures/symbol.rb +9 -7
- data/lib/data_model/fixtures/time.rb +13 -11
- data/lib/data_model/logging.rb +5 -8
- data/lib/data_model/model.rb +11 -8
- data/lib/data_model/registry.rb +129 -0
- data/lib/data_model/scanner.rb +24 -29
- data/lib/data_model/struct.rb +112 -0
- data/lib/data_model/testing/minitest.rb +33 -9
- data/lib/data_model/testing.rb +0 -2
- data/lib/data_model/type.rb +39 -23
- data/lib/data_model/version.rb +1 -3
- data/lib/data_model.rb +10 -19
- metadata +24 -21
- data/lib/data_model/type_registry.rb +0 -68
- data/sorbet/config +0 -4
- data/sorbet/rbi/annotations/rainbow.rbi +0 -269
- data/sorbet/rbi/gems/minitest@5.18.0.rbi +0 -1491
- data/sorbet/rbi/gems/zeitwerk.rbi +0 -196
- data/sorbet/rbi/gems/zeitwerk@2.6.7.rbi +0 -966
- data/sorbet/rbi/todo.rbi +0 -5
- data/sorbet/tapioca/config.yml +0 -13
- data/sorbet/tapioca/require.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c330ccaea1eb4d6a39ae646d1bfc1adea6fcea63398c393ca9daea37ad6c9345
|
4
|
+
data.tar.gz: 9ca8082aa99dd38e6c9838d089201be698713a2af312492d9f8d5c6d0512dddb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
7
|
-
-
|
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,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.
|
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
|
-
|
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 "
|
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
|
data/lib/data_model/boolean.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
9
|
-
prop :
|
10
|
-
prop :
|
11
|
-
prop :
|
12
|
-
prop :
|
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
|
-
#
|
16
|
-
|
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 =
|
34
|
+
@child_type = type
|
27
35
|
end
|
28
36
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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(
|
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(
|
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 =
|
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
|
-
|
8
|
-
|
9
|
-
prop :
|
10
|
-
prop :
|
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
|
-
|
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(
|
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(
|
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(
|
37
|
+
val = BigDecimal(val)
|
35
38
|
elsif val.respond_to?(:to_d)
|
36
|
-
val =
|
39
|
+
val = val.to_d
|
37
40
|
end
|
38
41
|
|
39
42
|
if !val.is_a?(BigDecimal)
|
40
|
-
err.add(coerce_error(
|
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
|
-
|
8
|
-
|
6
|
+
# Arguments for the boolean type
|
7
|
+
class Arguments < Struct
|
8
|
+
prop :optional, :boolean, default: false
|
9
9
|
end
|
10
10
|
|
11
|
-
|
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(
|
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(
|
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
|
-
|
8
|
-
|
9
|
-
prop :
|
10
|
-
prop :
|
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
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
8
|
-
|
9
|
-
prop :
|
10
|
-
prop :
|
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
|
-
|
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(
|
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(
|
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 =
|
39
|
+
val = val.to_f
|
37
40
|
end
|
38
41
|
|
39
42
|
if !val.is_a?(Float)
|
40
|
-
err.add(coerce_error(
|
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))
|