jsonite 0.0.1 → 0.0.2

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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/jsonite/version.rb +1 -1
  3. data/lib/jsonite.rb +147 -21
  4. metadata +34 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49c0a11e4a44bd3ab0ad87f0cbf27debc56afd10
4
- data.tar.gz: beeb10b2cc59a4e812c492cfba50bce34dfe5b4c
3
+ metadata.gz: 001f4ee4203a2a9ad449b3ce2be7bef23ba649dc
4
+ data.tar.gz: cf3d345ce6b1e7194edf8a009512b5a5873f3972
5
5
  SHA512:
6
- metadata.gz: bee8032685d34443435ef821aaa94b8fe0b4170ecc6e0a1fb55b6ed1bb1ae95346f8b50dce5f22c57d3673f1f7027b881291c5e9199f08bd12fbcdd5797a4321
7
- data.tar.gz: b3d8f45e00dd6164f2655988bbe6a5e2bc8880cde5ec1d9773087edc8518f047c07b2f8982e184d600c400d30ec847e0a2c05f29f3cb0fb54acfdf1fde65fe7b
6
+ metadata.gz: c819dffe0197681f90b17d6e86b5e219861538830c966d2b6f23e3497018c70e09d3070147a618684bb661ed8a42ee95d3c41f01d7e5a9c7bb8854ece3176746
7
+ data.tar.gz: 73ce6f0f49069b446b458347a3803d162b4bdd21d6ffd8ce74323d8e5e8a1f52b27a1a6d8b3c2a2e6d97c8496932d762dba5993bc332acf1fa1fc6b47e358b79
@@ -1,5 +1,5 @@
1
1
  class Jsonite
2
2
 
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
 
5
5
  end
data/lib/jsonite.rb CHANGED
@@ -1,14 +1,33 @@
1
+ require 'active_support/core_ext/object/blank'
2
+ require 'active_support/json/encoding'
1
3
  require 'jsonite/helper'
2
4
 
3
- # A simple JSON presenter for hypermedia applications.
4
- # Loosely adheers to HAL: http://stateless.co/hal_specification.html
5
-
5
+ # = Jsonite
6
+ #
7
+ # A tiny, HAL-compliant JSON presenter.
8
+ #
9
+ # http://tools.ietf.org/html/draft-kelly-json-hal-05
6
10
  class Jsonite
7
11
 
8
12
  class << self
9
13
 
14
+ # Presents a resource (or array of resources).
15
+ #
16
+ # class UserPresenter < Jsonite
17
+ # property :email
18
+ # end
19
+ # users = User.all
20
+ # UserPresenter.present(users.first)
21
+ # # => {"email"=>"stephen@example.com"}
22
+ # UserPresenter.present(users)
23
+ # # => [{"email"=>"stephen@example.com"}, ...]
24
+ #
25
+ # Configuration options:
26
+ # * <tt>:with</tt> - A specified presenter (defaults to `self`).
27
+ #
28
+ # All other options are passed along to <tt>#as_json</tt>.
10
29
  def present resource, options = {}
11
- presenter = options.fetch :with, self
30
+ presenter = options.delete(:with) { self }
12
31
 
13
32
  case resource
14
33
  when Jsonite
@@ -29,8 +48,27 @@ class Jsonite
29
48
  end
30
49
  end
31
50
 
51
+ # Defines a property to be exposed during presentation.
52
+ #
53
+ # class UserPresenter < Jsonite
54
+ # property :email
55
+ # end
56
+ # # {
57
+ # # "email": "stephen@example.com"
58
+ # # }
59
+ #
60
+ # Configuration options:
61
+ # * <tt>:with</tt> - A specified presenter. Ignored when a handler is
62
+ # present. Useful when you want to embed a resource as a property (rather
63
+ # than in the <tt>_embedded</tt> node).
32
64
  def property name, options = {}, &handler
33
- properties[name] = handler || proc { send name }
65
+ handler ||= if options[:with]
66
+ proc { Jsonite.present send(name), with: options[:with] }
67
+ else
68
+ proc { send name }
69
+ end
70
+
71
+ properties[name] = handler
34
72
  end
35
73
 
36
74
  def properties *properties
@@ -39,44 +77,123 @@ class Jsonite
39
77
  @properties
40
78
  end
41
79
 
42
- def embedded name, options = {}, &handler
43
- unless options[:with].is_a?(Class) && options[:with] <= Jsonite
44
- raise KeyError, ':with option must be a Jsonite'
45
- end
46
-
47
- property name, options do |context|
48
- resource = handler ? instance_exec(context, &handler) : send(name)
49
- present resource, { context: context, root: nil }.merge(options)
50
- end
51
- end
52
-
80
+ # Defines a link.
81
+ #
82
+ # class UserPresenter < Jsonite
83
+ # link do |context|
84
+ # context.user_url self
85
+ # end
86
+ # link :todos do |context|
87
+ # context.user_todos_url self
88
+ # end
89
+ # end
90
+ # # {
91
+ # # "_links": {
92
+ # # "self": {
93
+ # # "href": "http://example.com/users/8oljbpyjetu8"
94
+ # # },
95
+ # # "todos": {
96
+ # # "href": "http://example.com/users/8oljbpyjetu8/todos"
97
+ # # }
98
+ # # }
99
+ # # }
100
+ #
101
+ # Configuration options are displayed as additional properties on a link.
102
+ #
103
+ # class UserPresenter < Jsonite
104
+ # link :todos, title: 'To-dos', templated: true do |context|
105
+ # "#{context.user_todos_url self}{?done}
106
+ # end
107
+ # end
108
+ # # {
109
+ # # "_links": {
110
+ # # "todos": {
111
+ # # "href": "http://example.com/users/8oljbpyjetu8/todos{?done}",
112
+ # # "title": "To-dos",
113
+ # # "templated": true
114
+ # # }
115
+ # # }
116
+ # # }
53
117
  def link rel = :self, options = {}, &handler
54
- links[rel] = options.merge handler: handler
118
+ links[rel] = options.merge handler: Proc.new # enforce handler presence
55
119
  end
56
120
 
57
121
  def links
58
122
  @links ||= {}
59
123
  end
60
124
 
125
+ # Defines an embedded resource.
126
+ #
127
+ # class TodoPresenter < Jsonite
128
+ # property :description
129
+ # end
130
+ # class UserPresenter < Jsonite
131
+ # embed :todos, with: TodoPresenter
132
+ # end
133
+ # # {
134
+ # # "_embedded": {
135
+ # # "todos": [
136
+ # # {
137
+ # # "description": "Buy milk"
138
+ # # }
139
+ # # ]
140
+ # # }
141
+ # # }
142
+ #
143
+ # Configuration options:
144
+ # * <tt>:with</tt> - A specified presenter. Required if a handler isn't
145
+ # present.
146
+ def embed rel, options = {}, &handler
147
+ if handler.nil?
148
+ presenter = options.fetch :with
149
+ handler = proc do |context|
150
+ Jsonite.present send(rel), with: presenter, context: context
151
+ end
152
+ end
153
+
154
+ embedded[rel] = handler
155
+ end
156
+
157
+ def embedded
158
+ @embedded ||= {}
159
+ end
160
+
161
+ private
162
+
61
163
  def inherited presenter
62
164
  presenter.properties.update properties
63
165
  presenter.links.update links
166
+ presenter.embedded.update embedded
64
167
  end
65
168
 
66
169
  end
67
170
 
68
171
  attr_reader :resource, :defaults
69
172
 
173
+ # Initializes a new presenter instance with the given resource.
174
+ #
175
+ # Default options are passed to #as_json during presentation.
70
176
  def initialize resource, defaults = {}
71
177
  @resource, @defaults = resource, defaults
72
178
  end
73
179
 
180
+ # Returns a JSON representation (Hash) of the resource.
181
+ #
182
+ # Options:
183
+ # * <tt>:context</tt> - A context to pass a presenter instance while
184
+ # rendering properties, links, and embedded resources.
74
185
  def as_json options = {}
75
186
  return resource.as_json options if instance_of? Jsonite
76
- context, options = options.delete(:context), defaults.merge(options)
77
- properties(context).merge(_links: links(context)).as_json options
187
+ options = defaults.merge options
188
+ context = options.delete :context
189
+ hash = properties context
190
+ hash.update _links: links(context) if self.class.links.present?
191
+ hash.update _embedded: embedded(context) if self.class.embedded.present?
192
+ hash.as_json options
78
193
  end
79
194
 
195
+ private
196
+
80
197
  def properties context = nil
81
198
  context ||= resource
82
199
  self.class.properties.each_with_object({}) do |(name, handler), props|
@@ -88,10 +205,19 @@ class Jsonite
88
205
 
89
206
  def links context = nil
90
207
  context ||= resource
91
- self.class.links.each_with_object({}) do |(name, link), props|
208
+ self.class.links.each_with_object({}) do |(rel, link), links|
92
209
  catch :ignore do
93
210
  href = resource.instance_exec context, &link[:handler]
94
- props[name] = { href: href }.merge link.except :handler
211
+ links[rel] = { href: href }.merge link.except :handler
212
+ end
213
+ end
214
+ end
215
+
216
+ def embedded context = nil
217
+ context ||= resource
218
+ self.class.embedded.each_with_object({}) do |(name, handler), embedded|
219
+ catch :ignore do
220
+ embedded[name] = resource.instance_exec context, &handler
95
221
  end
96
222
  end
97
223
  end
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.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Celis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-31 00:00:00.000000000 Z
12
+ date: 2013-08-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -25,7 +25,35 @@ dependencies:
25
25
  - - '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: 3.1.0
28
- description: Tiny JSON presenter
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '='
33
+ - !ruby/object:Gem::Version
34
+ version: 10.1.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '='
40
+ - !ruby/object:Gem::Version
41
+ version: 10.1.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '='
47
+ - !ruby/object:Gem::Version
48
+ version: 2.14.1
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '='
54
+ - !ruby/object:Gem::Version
55
+ version: 2.14.1
56
+ description: Jsonite provides a very simple DSL to build HAL-compliant JSON presenters.
29
57
  email:
30
58
  - stephen@stephencelis.com
31
59
  - kainosnoema@gmail.com
@@ -37,7 +65,8 @@ files:
37
65
  - lib/jsonite/version.rb
38
66
  - lib/jsonite.rb
39
67
  homepage: https://github.com/barrelage/jsonite
40
- licenses: []
68
+ licenses:
69
+ - MIT
41
70
  metadata: {}
42
71
  post_install_message:
43
72
  rdoc_options: []
@@ -58,5 +87,5 @@ rubyforge_project:
58
87
  rubygems_version: 2.0.2
59
88
  signing_key:
60
89
  specification_version: 4
61
- summary: Tiny JSON presenter
90
+ summary: A tiny, HAL-compliant JSON presenter
62
91
  test_files: []