serial 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29eb0ebd62982d93650098a3f2f4f54f11879bf3
4
- data.tar.gz: 6d516f85165f6a46f767925a48c4d40d5a0cb1c9
3
+ metadata.gz: bfac09f4727b81d0b72935e00e38a5584f1203cf
4
+ data.tar.gz: aab5f90c21fa6356fda1c115b9e2a93cb71d694a
5
5
  SHA512:
6
- metadata.gz: 60d63e4986fc120337231c0ad4e0f1145947d6975e856fe61924c6760f3bb29c60218aafef65899015c19fb1a23241bf83558d81ca6b398a0b10fe7f5123d657
7
- data.tar.gz: 6922159d7d31c6e77abc2c9e1cc3f4b7b3fc3f1990afc8c6d5c11303e9364ef940ee21f3428a4be577764a476fd5c931b8507be74e673abd9f7b94e3b504f588
6
+ metadata.gz: 6e675f5cb4da83f143bec4fd7706e05a1267e35039e01192ed9268a44a7298dfe7807b3ef60047178b54079be4b92c252a71607ea8045f907d9b5dc2edd86eba
7
+ data.tar.gz: 8916083402ec5d799da188484c999bdaaf496def62156362f12b06c824f66c05e75ef1e857bd9cfac0e398220139b2293d06309c8d7523f520f4a4e75c6746f0
data/.yardopts CHANGED
@@ -1 +1,2 @@
1
1
  --asset elabs-logo.png
2
+ --files CODE_OF_CONDUCT.md,CHANGELOG.md
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.0.0
4
+
5
+ - Add HashBuilder#merge. [cb11a3c5]
6
+ - Raise an error by default if a key already exists in HashBuilder. [4b46db57]
7
+
3
8
  ## 0.2.0
4
9
 
5
10
  - Raise an error if serializer is not given a block.
@@ -0,0 +1,28 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all
4
+ people who contribute through reporting issues, posting feature requests,
5
+ updating documentation, submitting pull requests or patches, and other
6
+ activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, age, or religion.
12
+
13
+ Examples of unacceptable behavior by participants include the use of sexual
14
+ language or imagery, derogatory comments or personal attacks, trolling, public
15
+ or private harassment, insults, or other unprofessional conduct.
16
+
17
+ Project maintainers have the right and responsibility to remove, edit, or
18
+ reject comments, commits, code, wiki edits, issues, and other contributions
19
+ that are not aligned to this Code of Conduct. Project maintainers who do not
20
+ follow the Code of Conduct may be removed from the project team.
21
+
22
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
23
+ reported by opening an issue or contacting one or more of the project
24
+ maintainers.
25
+
26
+ This Code of Conduct is adapted from the [Contributor
27
+ Covenant](http:contributor-covenant.org), version 1.0.0, available at
28
+ [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/README.md CHANGED
@@ -36,9 +36,13 @@ And then execute:
36
36
 
37
37
  - All keys are turned into strings.
38
38
  - There is no automatic camel-casing. You name your keys the way you want them.
39
+ - Using the same key twice will raise an error by default.
40
+ - To override the value for an existing key, use the respective !-method DSL, i.e. `#attribute!`, `#collection!`, `#map!`, or `#merge!`.
39
41
 
40
42
  ### Simple attributes
41
43
 
44
+ `#attribute` creates a simple attribute with a value.
45
+
42
46
  ``` ruby
43
47
  ProjectSerializer = Serial::Serializer.new do |h, project|
44
48
  h.attribute(:id, project.id)
@@ -48,6 +52,8 @@ end # => { "id" => …, "displayName" => … }
48
52
 
49
53
  ### Nested attributes
50
54
 
55
+ `#attribute` supports nesting by giving it a block.
56
+
51
57
  ``` ruby
52
58
  ProjectSerializer = Serial::Serializer.new do |h, project|
53
59
  h.attribute(:owner, project.owner) do |h, owner|
@@ -85,6 +91,21 @@ ProjectSerializer = Serial::Serializer.new do |h, project|
85
91
  end # => { "indices" => [{…}, {…}, [{…}, {…}]] }
86
92
  ```
87
93
 
94
+ ### Merging
95
+
96
+ `#merge` will let you merge another serializer without introducing a new nesting level.
97
+
98
+ ``` ruby
99
+ ProjectSerializer = Serial::Serializer.new do |h, project|
100
+ h.attribute(:name, project.name)
101
+ end # => { "name" => … }
102
+
103
+ FullProjectSerializer = Serial::Serializer.new do |h, project|
104
+ h.merge(project, &ProjectSerializer)
105
+ h.attribute(:description, project.description)
106
+ end # { "name" => …, "description" => … }
107
+ ```
108
+
88
109
  ### Composition
89
110
 
90
111
  You can compose serializers by passing them as blocks to the DSL methods.
@@ -125,6 +146,13 @@ ProjectSerializer.map(context, projects) # => [{ … }, …]
125
146
 
126
147
  ### Using with Rails
127
148
 
149
+ ```ruby
150
+ # app/serializers/project_serializer.rb
151
+ ProjectSerializer = Serial::Serializer.new do |h, project|
152
+
153
+ end
154
+ ```
155
+
128
156
  ``` ruby
129
157
  # app/controllers/project_controller.rb
130
158
  class ProjectController < ApplicationController
@@ -161,7 +189,7 @@ git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygem
161
189
  Bug reports and pull requests are welcome on GitHub at
162
190
  https://github.com/elabs/serial. This project is intended to be a safe,
163
191
  welcoming space for collaboration, and contributors are expected to adhere to
164
- the [Contributor Covenant](contributor-covenant.org) code of conduct.
192
+ the [Contributor Covenant](CODE_OF_CONDUCT.md) code of conduct.
165
193
 
166
194
  ## License
167
195
 
@@ -7,4 +7,11 @@ require "serial/rails_helpers"
7
7
 
8
8
  # Serial namespace. See {Serial::Serializer} for reference.
9
9
  module Serial
10
+ # All serial-specific errors inherit from this error.
11
+ class Error < StandardError
12
+ end
13
+
14
+ # Raised when an already-defined key is defined again.
15
+ class DuplicateKeyError < StandardError
16
+ end
10
17
  end
@@ -30,8 +30,10 @@ module Serial
30
30
  def exec(*args, &block)
31
31
  if @context
32
32
  @context.instance_exec(self, *args, &block)
33
- else
33
+ elsif block
34
34
  block.call(self, *args)
35
+ else
36
+ raise ArgumentError, "no serializer block given"
35
37
  end
36
38
  end
37
39
  end
@@ -24,7 +24,20 @@ module Serial
24
24
  # @yield [builder, value] declare nested attribute if block is given
25
25
  # @yieldparam builder [HashBuilder] (keep in mind the examples shadow the outer `h` variable)
26
26
  # @yieldparam value
27
+ # @raise [DuplicateKeyError] if the same key has already been defined.
27
28
  def attribute(key, value = nil, &block)
29
+ check_duplicate_key!(key)
30
+ attribute!(key, value, &block)
31
+ end
32
+
33
+ # @api public
34
+ # Same as {#attribute}, but will not raise an error on duplicate keys.
35
+ #
36
+ # @see #attribute
37
+ # @param (see #attribute)
38
+ # @yield (see #attribute)
39
+ # @yieldparam (see #attribute)
40
+ def attribute!(key, value = nil, &block)
28
41
  value = HashBuilder.build(@context, value, &block) if block
29
42
  @data[key.to_s] = value
30
43
  end
@@ -49,9 +62,22 @@ module Serial
49
62
  #
50
63
  # @see ArrayBuilder
51
64
  # @param key [#to_s]
65
+ # @yield [builder]
52
66
  # @yieldparam builder [ArrayBuilder]
53
67
  def collection(key, &block)
54
- attribute(key, ArrayBuilder.build(@context, &block))
68
+ check_duplicate_key!(key)
69
+ collection!(key, &block)
70
+ end
71
+
72
+ # @api public
73
+ # Same as {#collection}, but will not raise an error on duplicate keys.
74
+ #
75
+ # @see #collection
76
+ # @param (see #collection)
77
+ # @yield (see #collection)
78
+ # @yieldparam (see #collection)
79
+ def collection!(key, &block)
80
+ attribute!(key, ArrayBuilder.build(@context, &block))
55
81
  end
56
82
 
57
83
  # @api public
@@ -69,7 +95,19 @@ module Serial
69
95
  # @yieldparam builder [HashBuilder]
70
96
  # @yieldparam value
71
97
  def map(key, list, &block)
72
- collection(key) do |builder|
98
+ check_duplicate_key!(key)
99
+ map!(key, list, &block)
100
+ end
101
+
102
+ # @api public
103
+ # Same as {#map}, but will not raise an error on duplicate keys.
104
+ #
105
+ # @see #map
106
+ # @param (see #map)
107
+ # @yield (see #map)
108
+ # @yieldparam (see #map)
109
+ def map!(key, list, &block)
110
+ collection!(key) do |builder|
73
111
  list.each do |item|
74
112
  builder.element do |element|
75
113
  element.exec(item, &block)
@@ -77,5 +115,48 @@ module Serial
77
115
  end
78
116
  end
79
117
  end
118
+
119
+ # @api public
120
+ # Merge another serializer into the current serialization.
121
+ #
122
+ # @example
123
+ # ExtendedProjectSerializer = Serial::Serializer.new do |h, project|
124
+ # h.merge(project, &ProjectSerializer)
125
+ # h.attribute(:extra, project.extra_info)
126
+ # end # => { "name" => …, …, "extra" => … }
127
+ #
128
+ # @param value
129
+ # @yield [builder, value] to another serializer
130
+ # @yieldparam builder [HashBuilder]
131
+ # @yieldparam value
132
+ # @raise [DuplicateKeyError] if a key to be merged is already defined.
133
+ def merge(value, &serializer)
134
+ hash = HashBuilder.build(@context, value, &serializer)
135
+ hash.keys.each { |key| check_duplicate_key!(key) }
136
+ @data.merge!(hash)
137
+ end
138
+
139
+ # @api public
140
+ # Same as {#merge}, but will not raise an error on duplicate keys.
141
+ #
142
+ # @see #merge
143
+ # @param (see #merge)
144
+ # @yield (see #merge)
145
+ # @yieldparam (see #merge)
146
+ def merge!(value, &serializer)
147
+ hash = HashBuilder.build(@context, value, &serializer)
148
+ @data.merge!(hash)
149
+ end
150
+
151
+ private
152
+
153
+ # @param key [#to_s]
154
+ # @raise [DuplicateKeyError] if key is defined
155
+ # @return [nil]
156
+ def check_duplicate_key!(key)
157
+ if @data.has_key?(key.to_s)
158
+ raise DuplicateKeyError, "'#{key}' is already defined"
159
+ end
160
+ end
80
161
  end
81
162
  end
@@ -1,6 +1,7 @@
1
1
  module Serial
2
2
  # Helpers for using Serial with Rails.
3
3
  module RailsHelpers
4
+ # @api public
4
5
  # Find the serializer for `model` and serialize it in the context of self.
5
6
  #
6
7
  # @example serializing a single object
@@ -17,6 +18,8 @@ module Serial
17
18
  #
18
19
  # @param context [#instance_exec]
19
20
  # @param model [#model_name, #each?]
21
+ # @yield [builder, model] yields if a block is given to use a custom serializer
22
+ # @yieldparam builder [HashBuilder]
20
23
  def serialize(context = self, model, &serializer)
21
24
  serializer &&= Serializer.new(&serializer)
22
25
  serializer ||= "#{model.model_name}Serializer".constantize
@@ -1,4 +1,4 @@
1
1
  module Serial
2
2
  # Gem version, uses SemVer.
3
- VERSION = "0.2.0"
3
+ VERSION = "1.0.0"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elabs
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2015-09-18 00:00:00.000000000 Z
13
+ date: 2015-09-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -110,6 +110,7 @@ files:
110
110
  - ".travis.yml"
111
111
  - ".yardopts"
112
112
  - CHANGELOG.md
113
+ - CODE_OF_CONDUCT.md
113
114
  - Gemfile
114
115
  - README.md
115
116
  - Rakefile