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.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -2
- data/.solargraph.yml +22 -0
- data/Gemfile.lock +71 -29
- data/Rakefile +0 -6
- data/Steepfile +27 -0
- data/data_model.gemspec +1 -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 +109 -36
- 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 +30 -18
- data/lib/data_model/errors.rb +79 -55
- 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 +37 -22
- data/lib/data_model/scanner.rb +23 -28
- data/lib/data_model/struct.rb +116 -0
- data/lib/data_model/testing/minitest.rb +33 -9
- data/lib/data_model/testing.rb +0 -2
- data/lib/data_model/type.rb +38 -22
- data/lib/data_model/version.rb +1 -3
- data/lib/data_model.rb +8 -17
- metadata +13 -26
- 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: f3a30187193b436d7dd863a4b2fe28d8baf21428d6fd936cb67555e9792786a7
|
4
|
+
data.tar.gz: e44e496aaf29d7ecd8dfd5633aae5275bb67a1ecfb821f7a64137f9532c36cca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
7
|
-
-
|
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.
|
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
|
-
|
43
|
+
logger (1.5.3)
|
44
|
+
lumberjack (1.2.9)
|
33
45
|
method_source (1.0.0)
|
34
|
-
minitest (5.
|
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.
|
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.
|
66
|
+
rbi (0.0.17)
|
52
67
|
ast
|
53
|
-
parser (>=
|
68
|
+
parser (>= 3.0.0)
|
54
69
|
sorbet-runtime (>= 0.5.9204)
|
55
|
-
unparser
|
56
|
-
|
57
|
-
|
58
|
-
|
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.
|
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.
|
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.
|
85
|
+
rubocop-ast (1.29.0)
|
69
86
|
parser (>= 3.2.1.0)
|
70
87
|
ruby-progressbar (1.13.0)
|
71
|
-
rufo (0.16.
|
88
|
+
rufo (0.16.2)
|
89
|
+
securerandom (0.2.2)
|
72
90
|
shellany (0.0.1)
|
73
|
-
sorbet (0.5.
|
74
|
-
sorbet-static (= 0.5.
|
75
|
-
sorbet-runtime (0.5.
|
76
|
-
sorbet-static (0.5.
|
77
|
-
sorbet-static-and-runtime (0.5.
|
78
|
-
sorbet (= 0.5.
|
79
|
-
sorbet-runtime (= 0.5.
|
80
|
-
spoom (1.2.
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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
|
-
|
157
|
+
steep
|
116
158
|
tapioca
|
117
159
|
|
118
160
|
BUNDLED WITH
|
119
|
-
2.4.
|
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 "
|
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
|
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))
|