ja2r 0.1.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 (6) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +40 -0
  4. data/lib/ja2r.rb +47 -0
  5. data/lib/ja2r/parser.rb +62 -0
  6. metadata +110 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9101887840b34ad6cf4e7b8834b345a323838324feb57d13555f850dfb2387a1
4
+ data.tar.gz: 80ca01099de24cfe5bbe193b3599a01f402c48ccddb731cc3877d0da3c1a068f
5
+ SHA512:
6
+ metadata.gz: ddbbbde349b73d8d7c1323ea82f424c13d73faf99eddc81985f5f58f0833c9d16fb20b8b739d59ffd8f946965d3d937b04c12d620bdb7d049fc35e5cad9652db
7
+ data.tar.gz: 9bc631cb1e2337f4604760434531d5d759f06bba5cc0885f9984fe34205998cb5f5fc8ada6b2f13732341e56e4a65212c25ab00b802ce73e2760bd3cf6a9aab2
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2018 Konstantin Munteanu
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # JA2R
2
+
3
+ JASON-API to Ruby Object
4
+
5
+ Converts a JSON-API payload into a ruby object which supports navigation over relationships.
6
+
7
+ ## Usage
8
+
9
+ ```ruby
10
+ json = <<-JSON
11
+ {
12
+ "data":{
13
+ "id":"1001",
14
+ "type":"persons",
15
+ "attributes":{
16
+ "name":"Bart"
17
+ },
18
+ "relationships":{
19
+ "sister":{
20
+ "data":{
21
+ "id":"1002",
22
+ "type":"persons"
23
+ }
24
+ }
25
+ }
26
+ },
27
+ "included":[
28
+ {
29
+ "id":"1002",
30
+ "type":"persons",
31
+ "attributes":{
32
+ "name":"Lisa"
33
+ }
34
+ }
35
+ ]
36
+ }
37
+ JSON
38
+ bart = JA2R.parse(JSON.parse(json))
39
+ bart.sister.name # Lisa
40
+ ```
data/lib/ja2r.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'active_support/core_ext/array'
2
+ require 'active_support/core_ext/hash'
3
+
4
+ module JA2R
5
+ autoload :Parser, 'ja2r/parser'
6
+
7
+ module_function
8
+
9
+ class Element
10
+ def initialize(payload)
11
+ @id = payload['id']
12
+ @type = payload['type']
13
+ @attributes = (payload['attributes'] || {}).with_indifferent_access
14
+ @relationships = payload['relationships'] ? convert_relationship(payload['relationships']) : {}
15
+ end
16
+
17
+ attr_reader :id, :type, :attributes, :relationships
18
+
19
+ private
20
+
21
+ def method_missing(method, *args)
22
+ return attributes[method] if attributes&.key? method
23
+ return relationships[method] if relationships&.key? method
24
+ super
25
+ end
26
+
27
+ def respond_to_missing?(symbol, include_all = false)
28
+ return true if attributes&.key?(symbol.to_s)
29
+ return true if relationships&.key?(symbol.to_s)
30
+ super
31
+ end
32
+
33
+ def convert_relationship(hash)
34
+ Hash[hash.map do |key, data|
35
+ if data.is_a? Array
36
+ [key, data.map { |d| Element.new(d) }]
37
+ else
38
+ [key, Element.new(data['data'])]
39
+ end
40
+ end].with_indifferent_access
41
+ end
42
+ end
43
+
44
+ def parse(hash)
45
+ Parser.new(hash).call
46
+ end
47
+ end
@@ -0,0 +1,62 @@
1
+ module JA2R
2
+ class Parser
3
+ def initialize(hash)
4
+ @hash = hash
5
+ @object_space = []
6
+ end
7
+
8
+ def call
9
+ data = parse_data
10
+ parse_included
11
+ object_space.each do |object|
12
+ assign_relationships object, object_map
13
+ end
14
+ data
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :hash, :object_space
20
+
21
+ def parse_data
22
+ hash['data'].is_a?(Array) ? parse_list : parse_single
23
+ end
24
+
25
+ def parse_single
26
+ root = Element.new hash['data']
27
+ object_space << root
28
+ root
29
+ end
30
+
31
+ def parse_list
32
+ root = hash['data'].map { |data| Element.new data }
33
+ object_space.push(*root)
34
+ root
35
+ end
36
+
37
+ def parse_included
38
+ hash['included']&.map do |data|
39
+ object_space.push Element.new(data)
40
+ end
41
+ end
42
+
43
+ def object_map
44
+ object_space.each_with_object({}) do |obj, ha|
45
+ ha.deep_merge! obj.type => {obj.id => obj}
46
+ end
47
+ end
48
+
49
+ def assign_relationships(element, object_space)
50
+ element.relationships.each do |key, relationship|
51
+ if relationship.is_a? Array
52
+ element.relationships[key] = relationship.map do |e|
53
+ object_space.dig(e.type, e.id) || e
54
+ end
55
+ else
56
+ next unless (obj = object_space.dig(relationship.type, relationship.id))
57
+ element.relationships[key] = obj
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ja2r
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - mkon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.2
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '6'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 5.0.2
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '6'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rspec
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.7'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.7'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rubocop
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.54.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '='
59
+ - !ruby/object:Gem::Version
60
+ version: 0.54.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: simplecov
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.16'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.16'
75
+ description:
76
+ email:
77
+ - konstantin@munteanu.de
78
+ executables: []
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - LICENSE
83
+ - README.md
84
+ - lib/ja2r.rb
85
+ - lib/ja2r/parser.rb
86
+ homepage: https://github.com/mkon/ja2r
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.7.6
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Simple JSON-API to ruby object conversion
110
+ test_files: []