jsi 0.0.4 → 0.4.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/.simplecov +3 -1
- data/CHANGELOG.md +48 -0
- data/LICENSE.md +613 -0
- data/README.md +84 -45
- data/jsi.gemspec +11 -14
- data/lib/jsi.rb +31 -12
- data/lib/jsi/base.rb +310 -344
- data/lib/jsi/base/to_rb.rb +2 -0
- data/lib/jsi/jsi_coder.rb +91 -0
- data/lib/jsi/json-schema-fragments.rb +3 -135
- data/lib/jsi/json.rb +3 -0
- data/lib/jsi/json/node.rb +72 -197
- data/lib/jsi/json/pointer.rb +419 -0
- data/lib/jsi/metaschema.rb +7 -0
- data/lib/jsi/metaschema_node.rb +218 -0
- data/lib/jsi/pathed_node.rb +118 -0
- data/lib/jsi/schema.rb +168 -223
- data/lib/jsi/schema_classes.rb +158 -0
- data/lib/jsi/simple_wrap.rb +12 -0
- data/lib/jsi/typelike_modules.rb +71 -45
- data/lib/jsi/util.rb +47 -57
- data/lib/jsi/version.rb +1 -1
- data/lib/schemas/json-schema.org/draft-04/schema.rb +7 -0
- data/lib/schemas/json-schema.org/draft-06/schema.rb +7 -0
- data/resources/icons/AGPL-3.0.png +0 -0
- data/test/base_array_test.rb +210 -84
- data/test/base_hash_test.rb +201 -58
- data/test/base_test.rb +212 -121
- data/test/jsi_coder_test.rb +85 -0
- data/test/jsi_json_arraynode_test.rb +26 -25
- data/test/jsi_json_hashnode_test.rb +40 -39
- data/test/jsi_json_node_test.rb +95 -126
- data/test/jsi_json_pointer_test.rb +102 -0
- data/test/jsi_typelike_as_json_test.rb +53 -0
- data/test/metaschema_node_test.rb +19 -0
- data/test/schema_module_test.rb +21 -0
- data/test/schema_test.rb +109 -97
- data/test/spreedly_openapi_test.rb +8 -0
- data/test/test_helper.rb +42 -8
- data/test/util_test.rb +14 -14
- metadata +54 -25
- data/LICENSE.txt +0 -21
- data/lib/jsi/schema_instance_json_coder.rb +0 -83
- data/lib/jsi/struct_json_coder.rb +0 -30
- data/test/schema_instance_json_coder_test.rb +0 -121
- data/test/struct_json_coder_test.rb +0 -130
data/test/test_helper.rb
CHANGED
@@ -2,8 +2,12 @@ require 'coveralls'
|
|
2
2
|
if Coveralls.will_run?
|
3
3
|
Coveralls.wear!
|
4
4
|
end
|
5
|
-
|
6
5
|
require 'simplecov'
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
|
9
|
+
require 'byebug'
|
10
|
+
|
7
11
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
8
12
|
require 'jsi'
|
9
13
|
|
@@ -16,8 +20,6 @@ require 'minitest/reporters'
|
|
16
20
|
|
17
21
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
18
22
|
|
19
|
-
require 'byebug'
|
20
|
-
|
21
23
|
class JSISpec < Minitest::Spec
|
22
24
|
if ENV['JSI_TEST_ALPHA']
|
23
25
|
# :nocov:
|
@@ -26,9 +28,41 @@ class JSISpec < Minitest::Spec
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def assert_equal exp, act, msg = nil
|
29
|
-
msg = message(msg, E)
|
31
|
+
msg = message(msg, E) do
|
32
|
+
[].tap do |ms|
|
33
|
+
ms << diff(exp, act)
|
34
|
+
ms << "#{ANSI.red { 'expected' }}: #{exp.inspect}"
|
35
|
+
ms << "#{ANSI.green { 'actual' }}: #{act.inspect}"
|
36
|
+
if exp.respond_to?(:to_str) && act.respond_to?(:to_str)
|
37
|
+
ms << "#{ANSI.red { 'expected (str)' }}:"
|
38
|
+
ms << exp
|
39
|
+
ms << "#{ANSI.green { 'actual (str)' }}:"
|
40
|
+
ms << act
|
41
|
+
end
|
42
|
+
end.join("\n")
|
43
|
+
end
|
30
44
|
assert exp == act, msg
|
31
45
|
end
|
46
|
+
|
47
|
+
def assert_match matcher, obj, msg = nil
|
48
|
+
msg = message(msg) do
|
49
|
+
[].tap do |ms|
|
50
|
+
ms << "Expected match."
|
51
|
+
ms << "#{ANSI.red { 'matcher' }}: #{mu_pp matcher}"
|
52
|
+
ms << "#{ANSI.green { 'object' }}: #{mu_pp obj}"
|
53
|
+
ms << "#{ANSI.yellow { 'escaped' }}: #{Regexp.new(Regexp.escape(obj)).inspect}" if obj.is_a?(String)
|
54
|
+
end.join("\n")
|
55
|
+
end
|
56
|
+
assert_respond_to matcher, :"=~"
|
57
|
+
matcher = Regexp.new Regexp.escape matcher if String === matcher
|
58
|
+
assert matcher =~ obj, msg
|
59
|
+
end
|
60
|
+
|
61
|
+
def assert_is_a mod, obj, msg = nil
|
62
|
+
msg = message(msg) { "Expected instance of #{mod}. received #{obj.class}: #{mu_pp(obj)}" }
|
63
|
+
|
64
|
+
assert obj.is_a?(mod), msg
|
65
|
+
end
|
32
66
|
end
|
33
67
|
|
34
68
|
# register this to be the base class for specs instead of Minitest::Spec
|
@@ -42,8 +76,8 @@ class SortOfHash
|
|
42
76
|
def to_hash
|
43
77
|
@hash
|
44
78
|
end
|
45
|
-
include JSI::FingerprintHash
|
46
|
-
def
|
79
|
+
include JSI::Util::FingerprintHash
|
80
|
+
def jsi_fingerprint
|
47
81
|
{class: self.class, hash: @hash}
|
48
82
|
end
|
49
83
|
end
|
@@ -56,8 +90,8 @@ class SortOfArray
|
|
56
90
|
def to_ary
|
57
91
|
@ary
|
58
92
|
end
|
59
|
-
include JSI::FingerprintHash
|
60
|
-
def
|
93
|
+
include JSI::Util::FingerprintHash
|
94
|
+
def jsi_fingerprint
|
61
95
|
{class: self.class, ary: @ary}
|
62
96
|
end
|
63
97
|
end
|
data/test/util_test.rb
CHANGED
@@ -6,24 +6,24 @@ describe JSI::Util do
|
|
6
6
|
assert_equal({'a' => 'b', 'c' => 'd', nil => 3}, JSI.stringify_symbol_keys({a: 'b', 'c' => 'd', nil => 3}))
|
7
7
|
end
|
8
8
|
it 'stringifies HashNode keys' do
|
9
|
-
actual = JSI.stringify_symbol_keys(JSI::JSON::
|
10
|
-
expected = JSI::JSON::
|
9
|
+
actual = JSI.stringify_symbol_keys(JSI::JSON::Node.new_doc({a: 'b', 'c' => 'd', nil => 3}))
|
10
|
+
expected = JSI::JSON::Node.new_doc({'a' => 'b', 'c' => 'd', nil => 3})
|
11
11
|
assert_equal(expected, actual)
|
12
12
|
end
|
13
13
|
it 'stringifies JSI hash keys' do
|
14
|
-
|
15
|
-
expected = JSI.stringify_symbol_keys(
|
16
|
-
actual =
|
14
|
+
schema = JSI::Schema.new({type: 'object'})
|
15
|
+
expected = JSI.stringify_symbol_keys(schema.new_jsi({a: 'b', 'c' => 'd', nil => 3}))
|
16
|
+
actual = schema.new_jsi({'a' => 'b', 'c' => 'd', nil => 3})
|
17
17
|
assert_equal(expected, actual)
|
18
18
|
end
|
19
19
|
describe 'non-hash-like argument' do
|
20
20
|
it 'errors' do
|
21
21
|
err = assert_raises(ArgumentError) { JSI.stringify_symbol_keys(nil) }
|
22
22
|
assert_equal("expected argument to be a hash; got NilClass: nil", err.message)
|
23
|
-
err = assert_raises(ArgumentError) { JSI.stringify_symbol_keys(JSI::JSON::Node.
|
24
|
-
assert_equal("expected argument to be a hash; got JSI::JSON::Node: #<JSI::JSON::Node
|
25
|
-
err = assert_raises(ArgumentError) { JSI.stringify_symbol_keys(JSI.
|
26
|
-
|
23
|
+
err = assert_raises(ArgumentError) { JSI.stringify_symbol_keys(JSI::JSON::Node.new_doc(3)) }
|
24
|
+
assert_equal("expected argument to be a hash; got JSI::JSON::Node: #<JSI::JSON::Node # 3>", err.message)
|
25
|
+
err = assert_raises(ArgumentError) { JSI.stringify_symbol_keys(JSI::Schema.new({}).new_jsi(3)) }
|
26
|
+
assert_equal("expected argument to be a hash; got (JSI Schema Class: #): #<JSI 3>", err.message)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -48,14 +48,14 @@ describe JSI::Util do
|
|
48
48
|
assert_equal(expected, actual)
|
49
49
|
end
|
50
50
|
it 'deep stringifies HashNode keys' do
|
51
|
-
actual = JSI.deep_stringify_symbol_keys(JSI::JSON::
|
52
|
-
expected = JSI::JSON::
|
51
|
+
actual = JSI.deep_stringify_symbol_keys(JSI::JSON::Node.new_doc({a: 'b', 'c' => {d: 0}, nil => 3}))
|
52
|
+
expected = JSI::JSON::Node.new_doc({'a' => 'b', 'c' => {'d' => 0}, nil => 3})
|
53
53
|
assert_equal(expected, actual)
|
54
54
|
end
|
55
55
|
it 'deep stringifies JSI instance' do
|
56
|
-
|
57
|
-
actual = JSI.deep_stringify_symbol_keys(
|
58
|
-
expected =
|
56
|
+
schema = JSI::Schema.new(type: 'object')
|
57
|
+
actual = JSI.deep_stringify_symbol_keys(schema.new_jsi(JSI::JSON::Node.new_doc({a: 'b', 'c' => {d: 0}, nil => 3})))
|
58
|
+
expected = schema.new_jsi(JSI::JSON::Node.new_doc({'a' => 'b', 'c' => {'d' => 0}, nil => 3}))
|
59
59
|
assert_equal(expected, actual)
|
60
60
|
end
|
61
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-schema
|
@@ -28,30 +28,30 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest-around
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,10 +80,24 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
|
84
|
-
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: scorpio
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: JSI offers an Object-Oriented representation for JSON data using JSON
|
98
|
+
Schemas
|
85
99
|
email:
|
86
|
-
- ethan@unth
|
100
|
+
- ethan.jsi@unth.net
|
87
101
|
executables: []
|
88
102
|
extensions: []
|
89
103
|
extra_rdoc_files: []
|
@@ -91,37 +105,49 @@ files:
|
|
91
105
|
- ".simplecov"
|
92
106
|
- ".yardopts"
|
93
107
|
- CHANGELOG.md
|
94
|
-
- LICENSE.
|
108
|
+
- LICENSE.md
|
95
109
|
- README.md
|
96
110
|
- Rakefile.rb
|
97
111
|
- jsi.gemspec
|
98
112
|
- lib/jsi.rb
|
99
113
|
- lib/jsi/base.rb
|
100
114
|
- lib/jsi/base/to_rb.rb
|
115
|
+
- lib/jsi/jsi_coder.rb
|
101
116
|
- lib/jsi/json-schema-fragments.rb
|
102
117
|
- lib/jsi/json.rb
|
103
118
|
- lib/jsi/json/node.rb
|
119
|
+
- lib/jsi/json/pointer.rb
|
120
|
+
- lib/jsi/metaschema.rb
|
121
|
+
- lib/jsi/metaschema_node.rb
|
122
|
+
- lib/jsi/pathed_node.rb
|
104
123
|
- lib/jsi/schema.rb
|
105
|
-
- lib/jsi/
|
106
|
-
- lib/jsi/
|
124
|
+
- lib/jsi/schema_classes.rb
|
125
|
+
- lib/jsi/simple_wrap.rb
|
107
126
|
- lib/jsi/typelike_modules.rb
|
108
127
|
- lib/jsi/util.rb
|
109
128
|
- lib/jsi/version.rb
|
129
|
+
- lib/schemas/json-schema.org/draft-04/schema.rb
|
130
|
+
- lib/schemas/json-schema.org/draft-06/schema.rb
|
131
|
+
- resources/icons/AGPL-3.0.png
|
110
132
|
- test/base_array_test.rb
|
111
133
|
- test/base_hash_test.rb
|
112
134
|
- test/base_test.rb
|
135
|
+
- test/jsi_coder_test.rb
|
113
136
|
- test/jsi_json_arraynode_test.rb
|
114
137
|
- test/jsi_json_hashnode_test.rb
|
115
138
|
- test/jsi_json_node_test.rb
|
139
|
+
- test/jsi_json_pointer_test.rb
|
116
140
|
- test/jsi_test.rb
|
117
|
-
- test/
|
141
|
+
- test/jsi_typelike_as_json_test.rb
|
142
|
+
- test/metaschema_node_test.rb
|
143
|
+
- test/schema_module_test.rb
|
118
144
|
- test/schema_test.rb
|
119
|
-
- test/
|
145
|
+
- test/spreedly_openapi_test.rb
|
120
146
|
- test/test_helper.rb
|
121
147
|
- test/util_test.rb
|
122
148
|
homepage: https://github.com/notEthan/jsi
|
123
149
|
licenses:
|
124
|
-
-
|
150
|
+
- AGPL-3.0
|
125
151
|
metadata: {}
|
126
152
|
post_install_message:
|
127
153
|
rdoc_options: []
|
@@ -138,21 +164,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
164
|
- !ruby/object:Gem::Version
|
139
165
|
version: '0'
|
140
166
|
requirements: []
|
141
|
-
|
142
|
-
rubygems_version: 2.7.8
|
167
|
+
rubygems_version: 3.0.6
|
143
168
|
signing_key:
|
144
169
|
specification_version: 4
|
145
|
-
summary: 'JSI: JSON
|
170
|
+
summary: 'JSI: JSON Schema Instantiation'
|
146
171
|
test_files:
|
147
172
|
- test/base_array_test.rb
|
148
173
|
- test/base_hash_test.rb
|
149
174
|
- test/base_test.rb
|
175
|
+
- test/jsi_coder_test.rb
|
150
176
|
- test/jsi_json_arraynode_test.rb
|
151
177
|
- test/jsi_json_hashnode_test.rb
|
152
178
|
- test/jsi_json_node_test.rb
|
179
|
+
- test/jsi_json_pointer_test.rb
|
153
180
|
- test/jsi_test.rb
|
154
|
-
- test/
|
181
|
+
- test/jsi_typelike_as_json_test.rb
|
182
|
+
- test/metaschema_node_test.rb
|
183
|
+
- test/schema_module_test.rb
|
155
184
|
- test/schema_test.rb
|
156
|
-
- test/
|
185
|
+
- test/spreedly_openapi_test.rb
|
157
186
|
- test/test_helper.rb
|
158
187
|
- test/util_test.rb
|
data/LICENSE.txt
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2016 Ethan
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
13
|
-
all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
@@ -1,83 +0,0 @@
|
|
1
|
-
module JSI
|
2
|
-
# this is a ActiveRecord serialization class intended to store JSON in the
|
3
|
-
# database column and expose a ruby class once loaded on a model instance.
|
4
|
-
# this allows for better ruby idioms to access to properties, and definition
|
5
|
-
# of related methods on the loaded class.
|
6
|
-
#
|
7
|
-
# the first argument, `loaded_class`, is the class which will be used to
|
8
|
-
# instantiate the column data. properties of the loaded class will correspond
|
9
|
-
# to keys of the json object in the database.
|
10
|
-
#
|
11
|
-
# the column data may be either a single instance of the loaded class
|
12
|
-
# (represented as one json object) or an array of them (represented as a json
|
13
|
-
# array of json objects), indicated by the keyword argument `array`.
|
14
|
-
#
|
15
|
-
# the column behind the attribute may be an actual JSON column (postgres json
|
16
|
-
# or jsonb - hstore should work too if you only have string attributes) or a
|
17
|
-
# serialized string, indicated by the keyword argument `string`.
|
18
|
-
class ObjectJSONCoder
|
19
|
-
class Error < StandardError
|
20
|
-
end
|
21
|
-
class LoadError < Error
|
22
|
-
end
|
23
|
-
class DumpError < Error
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(loaded_class, string: false, array: false, next_coder: nil)
|
27
|
-
@loaded_class = loaded_class
|
28
|
-
# this notes the order of the keys as they were in the json, used by dump_object to generate
|
29
|
-
# json that is equivalent to the json/jsonifiable that came in, so that AR's #changed_attributes
|
30
|
-
# can tell whether the attribute has been changed.
|
31
|
-
@loaded_class.send(:attr_accessor, :object_json_coder_keys_order)
|
32
|
-
@string = string
|
33
|
-
@array = array
|
34
|
-
@next_coder = next_coder
|
35
|
-
end
|
36
|
-
|
37
|
-
def load(column_data)
|
38
|
-
return nil if column_data.nil?
|
39
|
-
data = @string ? ::JSON.parse(column_data) : column_data
|
40
|
-
object = if @array
|
41
|
-
unless data.respond_to?(:to_ary)
|
42
|
-
raise TypeError, "expected array-like column data; got: #{data.class}: #{data.inspect}"
|
43
|
-
end
|
44
|
-
data.map { |el| load_object(el) }
|
45
|
-
else
|
46
|
-
load_object(data)
|
47
|
-
end
|
48
|
-
object = @next_coder.load(object) if @next_coder
|
49
|
-
object
|
50
|
-
end
|
51
|
-
|
52
|
-
def dump(object)
|
53
|
-
object = @next_coder.dump(object) if @next_coder
|
54
|
-
return nil if object.nil?
|
55
|
-
jsonifiable = begin
|
56
|
-
if @array
|
57
|
-
unless object.respond_to?(:to_ary)
|
58
|
-
raise DumpError, "expected array-like attribute; got: #{object.class}: #{object.inspect}"
|
59
|
-
end
|
60
|
-
object.map do |el|
|
61
|
-
dump_object(el)
|
62
|
-
end
|
63
|
-
else
|
64
|
-
dump_object(object)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
@string ? ::JSON.generate(jsonifiable) : jsonifiable
|
68
|
-
end
|
69
|
-
end
|
70
|
-
# this is a ActiveRecord serialization class intended to store JSON in the
|
71
|
-
# database column and expose a given JSI::Base subclass once loaded
|
72
|
-
# on a model instance.
|
73
|
-
class SchemaInstanceJSONCoder < ObjectJSONCoder
|
74
|
-
private
|
75
|
-
def load_object(data)
|
76
|
-
@loaded_class.new(data)
|
77
|
-
end
|
78
|
-
|
79
|
-
def dump_object(object)
|
80
|
-
JSI::Typelike.as_json(object)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module JSI
|
2
|
-
# this is a ActiveRecord serialization class intended to store JSON in the
|
3
|
-
# database column and expose a Struct subclass once loaded on a model instance.
|
4
|
-
class StructJSONCoder < ObjectJSONCoder
|
5
|
-
private
|
6
|
-
def load_object(data)
|
7
|
-
if data.is_a?(Hash)
|
8
|
-
good_keys = @loaded_class.members.map(&:to_s)
|
9
|
-
bad_keys = data.keys - good_keys
|
10
|
-
unless bad_keys.empty?
|
11
|
-
raise LoadError, "expected keys #{good_keys}; got unrecognized keys: #{bad_keys}"
|
12
|
-
end
|
13
|
-
instance = @loaded_class.new(*@loaded_class.members.map { |m| data[m.to_s] })
|
14
|
-
instance.object_json_coder_keys_order = data.keys
|
15
|
-
instance
|
16
|
-
else
|
17
|
-
raise LoadError, "expected instance(s) of #{Hash}; got: #{data.class}: #{data.inspect}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def dump_object(object)
|
22
|
-
if object.is_a?(@loaded_class)
|
23
|
-
keys = (object.object_json_coder_keys_order || []) | @loaded_class.members.map(&:to_s)
|
24
|
-
keys.map { |member| {member => object[member]} }.inject({}, &:update)
|
25
|
-
else
|
26
|
-
raise TypeError, "expected instance(s) of #{@loaded_class}; got: #{object.class}: #{object.inspect}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|