jsonite 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|