jsonite 0.0.2 → 0.0.3
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/lib/jsonite.rb +84 -56
- data/lib/jsonite/helper.rb +1 -1
- data/lib/jsonite/lets_proxy.rb +23 -0
- data/lib/jsonite/version.rb +1 -1
- metadata +24 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5612be53563ec019fa0b12169f778105d529896c
|
4
|
+
data.tar.gz: f19a895e932ae5b559f5de7699c39df930189713
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3273041c6a95535e89442a3d99ddf8bf6e2fe8dc3ce94d1a8e2c109a50f4b915a98ffc0ecefcfd42e3f026d7524993f9b3e9c1421b76bf0c8dc4c55e0af9c462
|
7
|
+
data.tar.gz: 461ea18c18c82ee91734e644cebfea19a733b2951a072ce39b4ca0244f7a1a3c2a9d1eca3657e7afb45a289ff1e7aa9c0accf6ddffe47ae0463b5065a0841db5
|
data/lib/jsonite.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_support/core_ext/object/blank'
|
2
2
|
require 'active_support/json/encoding'
|
3
3
|
require 'jsonite/helper'
|
4
|
+
require 'jsonite/lets_proxy'
|
4
5
|
|
5
6
|
# = Jsonite
|
6
7
|
#
|
@@ -23,29 +24,25 @@ class Jsonite
|
|
23
24
|
# # => [{"email"=>"stephen@example.com"}, ...]
|
24
25
|
#
|
25
26
|
# Configuration options:
|
27
|
+
# * <tt>:root</tt> - A root key to wrap the resource with.
|
26
28
|
# * <tt>:with</tt> - A specified presenter (defaults to `self`).
|
27
29
|
#
|
28
|
-
# All other options are passed along to <tt>#
|
30
|
+
# All other options are passed along to <tt>#present</tt>.
|
29
31
|
def present resource, options = {}
|
30
32
|
presenter = options.delete(:with) { self }
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
resource.to_ary.map do |r|
|
38
|
-
present presenter.new(r), options.merge(root: nil)
|
39
|
-
end
|
40
|
-
elsif resource.respond_to?(:as_json)
|
41
|
-
present presenter.new(resource), options.merge(root: nil)
|
42
|
-
else
|
43
|
-
resource
|
34
|
+
presented = if resource.is_a? Jsonite
|
35
|
+
resource.present options
|
36
|
+
elsif resource.respond_to?(:to_ary)
|
37
|
+
resource.to_ary.map do |member|
|
38
|
+
presenter.new(member).present options.merge root: nil
|
44
39
|
end
|
45
|
-
|
46
|
-
|
47
|
-
root ? { root => resource } : resource
|
40
|
+
else
|
41
|
+
presenter.new(resource).present options.merge root: nil
|
48
42
|
end
|
43
|
+
|
44
|
+
root = options.fetch(:root) { Helper.resource_name(resource) }
|
45
|
+
root ? { root => presented } : presented
|
49
46
|
end
|
50
47
|
|
51
48
|
# Defines a property to be exposed during presentation.
|
@@ -61,14 +58,9 @@ class Jsonite
|
|
61
58
|
# * <tt>:with</tt> - A specified presenter. Ignored when a handler is
|
62
59
|
# present. Useful when you want to embed a resource as a property (rather
|
63
60
|
# than in the <tt>_embedded</tt> node).
|
61
|
+
# * <tt>:ignore_nil</tt> - Ignore `nil`.
|
64
62
|
def property name, options = {}, &handler
|
65
|
-
handler
|
66
|
-
proc { Jsonite.present send(name), with: options[:with] }
|
67
|
-
else
|
68
|
-
proc { send name }
|
69
|
-
end
|
70
|
-
|
71
|
-
properties[name] = handler
|
63
|
+
properties[name.to_s] = { handler: handler }.merge options
|
72
64
|
end
|
73
65
|
|
74
66
|
def properties *properties
|
@@ -102,7 +94,7 @@ class Jsonite
|
|
102
94
|
#
|
103
95
|
# class UserPresenter < Jsonite
|
104
96
|
# link :todos, title: 'To-dos', templated: true do |context|
|
105
|
-
# "#{context.user_todos_url self}{?done}
|
97
|
+
# "#{context.user_todos_url self}{?done}"
|
106
98
|
# end
|
107
99
|
# end
|
108
100
|
# # {
|
@@ -115,7 +107,7 @@ class Jsonite
|
|
115
107
|
# # }
|
116
108
|
# # }
|
117
109
|
def link rel = :self, options = {}, &handler
|
118
|
-
links[rel] =
|
110
|
+
links[rel.to_s] = { handler: Proc.new }.merge options # require handler
|
119
111
|
end
|
120
112
|
|
121
113
|
def links
|
@@ -143,27 +135,40 @@ class Jsonite
|
|
143
135
|
# Configuration options:
|
144
136
|
# * <tt>:with</tt> - A specified presenter. Required if a handler isn't
|
145
137
|
# present.
|
138
|
+
# * <tt>:ignore_nil</tt> - Ignore `nil`.
|
146
139
|
def embed rel, options = {}, &handler
|
147
|
-
|
148
|
-
|
149
|
-
handler = proc do |context|
|
150
|
-
Jsonite.present send(rel), with: presenter, context: context
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
embedded[rel] = handler
|
140
|
+
options.fetch :with unless handler
|
141
|
+
embedded[rel.to_s] = { handler: handler }.merge options
|
155
142
|
end
|
156
143
|
|
157
144
|
def embedded
|
158
145
|
@embedded ||= {}
|
159
146
|
end
|
160
147
|
|
148
|
+
# Defines a memoized "virtual" method on the resource.
|
149
|
+
#
|
150
|
+
# class UserPresenter < Jsonite
|
151
|
+
# let(:full_name) { "#{first_name} #{last_name}" }
|
152
|
+
# property :full_name
|
153
|
+
# end
|
154
|
+
# # {
|
155
|
+
# # "full_name": "Stephen Celis"
|
156
|
+
# # }
|
157
|
+
def let name, &handler
|
158
|
+
lets[name.to_s] = handler
|
159
|
+
end
|
160
|
+
|
161
|
+
def lets
|
162
|
+
@lets ||= {}
|
163
|
+
end
|
164
|
+
|
161
165
|
private
|
162
166
|
|
163
167
|
def inherited presenter
|
164
168
|
presenter.properties.update properties
|
165
169
|
presenter.links.update links
|
166
170
|
presenter.embedded.update embedded
|
171
|
+
presenter.lets.update lets
|
167
172
|
end
|
168
173
|
|
169
174
|
end
|
@@ -177,49 +182,72 @@ class Jsonite
|
|
177
182
|
@resource, @defaults = resource, defaults
|
178
183
|
end
|
179
184
|
|
180
|
-
# Returns a
|
185
|
+
# Returns a raw representation (Hash) of the resource.
|
181
186
|
#
|
182
187
|
# Options:
|
183
188
|
# * <tt>:context</tt> - A context to pass a presenter instance while
|
184
189
|
# rendering properties, links, and embedded resources.
|
185
|
-
def
|
186
|
-
return resource.as_json options if instance_of? Jsonite
|
190
|
+
def present options = {}
|
187
191
|
options = defaults.merge options
|
192
|
+
|
188
193
|
context = options.delete :context
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
194
|
+
proxied = LetsProxy.new resource, context, self.class.lets
|
195
|
+
|
196
|
+
presented = properties proxied, context
|
197
|
+
_links = links proxied, context
|
198
|
+
presented['_links'] = _links if _links.present?
|
199
|
+
_embedded = embedded proxied, context
|
200
|
+
presented['_embedded'] = _embedded if _embedded.present?
|
201
|
+
|
202
|
+
root = options.fetch(:root) { Helper.resource_name(resource) }
|
203
|
+
root ? { root => presented } : presented
|
204
|
+
end
|
205
|
+
|
206
|
+
# Returns a JSON-ready representation (Hash) of the resource.
|
207
|
+
#
|
208
|
+
# Options:
|
209
|
+
# * <tt>:root</tt>
|
210
|
+
def as_json options = {}
|
211
|
+
present(options).as_json options
|
193
212
|
end
|
194
213
|
|
195
214
|
private
|
196
215
|
|
197
|
-
def properties context = nil
|
198
|
-
|
199
|
-
|
200
|
-
catch :ignore do
|
201
|
-
props[name] = resource.instance_exec context, &handler
|
202
|
-
end
|
216
|
+
def properties rsrc, context = nil
|
217
|
+
self.class.properties.each_with_object({}) do |(name, options), props|
|
218
|
+
catch(:ignore) { props[name] = fetch name, rsrc, context, options }
|
203
219
|
end
|
204
220
|
end
|
205
221
|
|
206
|
-
def links context = nil
|
207
|
-
context ||= resource
|
222
|
+
def links rsrc, context = nil
|
208
223
|
self.class.links.each_with_object({}) do |(rel, link), links|
|
209
224
|
catch :ignore do
|
210
|
-
href =
|
211
|
-
links[rel] = { href
|
225
|
+
href = fetch rel, rsrc, context, link
|
226
|
+
links[rel] = { 'href' => href }.merge link.except :handler
|
212
227
|
end
|
213
228
|
end
|
214
229
|
end
|
215
230
|
|
216
|
-
def embedded context = nil
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
231
|
+
def embedded rsrc, context = nil
|
232
|
+
self.class.embedded.each_with_object({}) do |(name, options), embeds|
|
233
|
+
catch(:ignore) { embeds[name] = fetch name, rsrc, context, options }
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def fetch name, rsrc, context, options
|
238
|
+
value = if options[:handler]
|
239
|
+
rsrc.instance_exec context, &options[:handler]
|
240
|
+
else
|
241
|
+
rsrc.__send__ name
|
222
242
|
end
|
243
|
+
|
244
|
+
throw :ignore if options[:ignore_nil] && value.nil?
|
245
|
+
|
246
|
+
if options[:with] && !value.nil?
|
247
|
+
return options[:with].present value, context: context, root: nil
|
248
|
+
end
|
249
|
+
|
250
|
+
value
|
223
251
|
end
|
224
252
|
|
225
253
|
end
|
data/lib/jsonite/helper.rb
CHANGED
@@ -6,7 +6,7 @@ class Jsonite
|
|
6
6
|
module_function
|
7
7
|
|
8
8
|
def resource_name resource
|
9
|
-
if resource.respond_to? :
|
9
|
+
if resource.respond_to?(:model_name) && resource.respond_to?(:to_ary)
|
10
10
|
resource.model_name.collection
|
11
11
|
elsif resource.class.respond_to? :model_name
|
12
12
|
resource.class.model_name.singular
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Jsonite
|
2
|
+
class LetsProxy < BasicObject
|
3
|
+
|
4
|
+
undef_method :==, :!, :!=
|
5
|
+
|
6
|
+
def initialize object, context, lets = {}
|
7
|
+
@__object__, @__context__, @__lets__ = object, context, lets
|
8
|
+
|
9
|
+
@__memoized__ = ::Hash.new do |memoized, name|
|
10
|
+
memoized[name] = instance_exec @__context__, &@__lets__.fetch(name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing name, *args, &block
|
15
|
+
if @__lets__.key?(name.to_s)
|
16
|
+
@__memoized__[name.to_s]
|
17
|
+
else
|
18
|
+
@__object__.__send__ name, *args, &block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/jsonite/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Celis
|
@@ -9,20 +9,34 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-05-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 3.1.0
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 3.1.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activemodel
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 3.1.0
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
26
40
|
- !ruby/object:Gem::Version
|
27
41
|
version: 3.1.0
|
28
42
|
- !ruby/object:Gem::Dependency
|
@@ -61,9 +75,10 @@ executables: []
|
|
61
75
|
extensions: []
|
62
76
|
extra_rdoc_files: []
|
63
77
|
files:
|
78
|
+
- lib/jsonite.rb
|
64
79
|
- lib/jsonite/helper.rb
|
80
|
+
- lib/jsonite/lets_proxy.rb
|
65
81
|
- lib/jsonite/version.rb
|
66
|
-
- lib/jsonite.rb
|
67
82
|
homepage: https://github.com/barrelage/jsonite
|
68
83
|
licenses:
|
69
84
|
- MIT
|
@@ -74,18 +89,19 @@ require_paths:
|
|
74
89
|
- lib
|
75
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
76
91
|
requirements:
|
77
|
-
- -
|
92
|
+
- - ">="
|
78
93
|
- !ruby/object:Gem::Version
|
79
94
|
version: 1.9.3
|
80
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
96
|
requirements:
|
82
|
-
- -
|
97
|
+
- - ">="
|
83
98
|
- !ruby/object:Gem::Version
|
84
99
|
version: '0'
|
85
100
|
requirements: []
|
86
101
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.
|
102
|
+
rubygems_version: 2.2.2
|
88
103
|
signing_key:
|
89
104
|
specification_version: 4
|
90
105
|
summary: A tiny, HAL-compliant JSON presenter
|
91
106
|
test_files: []
|
107
|
+
has_rdoc: false
|