media_types 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +44 -44
- data/README.md +379 -347
- data/lib/media_types/constructable.rb +12 -16
- data/lib/media_types/dsl.rb +7 -0
- data/lib/media_types/formatter.rb +55 -0
- data/lib/media_types/scheme.rb +59 -131
- data/lib/media_types/scheme/allow_nil.rb +2 -10
- data/lib/media_types/scheme/any_of.rb +4 -0
- data/lib/media_types/scheme/attribute.rb +4 -0
- data/lib/media_types/scheme/enumeration_context.rb +5 -3
- data/lib/media_types/scheme/enumeration_of_type.rb +4 -0
- data/lib/media_types/scheme/errors.rb +21 -0
- data/lib/media_types/scheme/links.rb +18 -12
- data/lib/media_types/scheme/missing_validation.rb +1 -1
- data/lib/media_types/scheme/not_strict.rb +4 -0
- data/lib/media_types/scheme/output_empty_guard.rb +40 -0
- data/lib/media_types/scheme/output_iterator_with_predicate.rb +55 -0
- data/lib/media_types/scheme/output_type_guard.rb +39 -0
- data/lib/media_types/scheme/rules.rb +84 -0
- data/lib/media_types/scheme/rules_exhausted_guard.rb +62 -0
- data/lib/media_types/version.rb +5 -5
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54061285d1504ab09d4fc7299bf242ad4e0a7529
|
4
|
+
data.tar.gz: d1cff5bf120ff2f5cd570887f3e351117466e54e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 283abdbba4639fbabb39223ed943c495289a2a2f607055e1c00d1b789d6612d604d3de5b7bf4d4e5d644acd9e4d46316e2e92319354f71278059f0c42697b5eb
|
7
|
+
data.tar.gz: 2a57915b68ebab50f5820ee472499aea29d9bbeaa17f5cab416419c8ab3acba7f094c1934c50e2458b9c3728f71c5c6f845de6ec6e6e55bac666143ff48030dd
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
# 0.5.0
|
2
|
+
|
3
|
+
- Change internal representation of key to symbol
|
4
|
+
- Change default type from `nil` to `Object`, removing special behaviour for nil
|
5
|
+
- Add `Rules` class to handle normalization of keys and handling `rules` (`Scheme`, `Attribute`, etc)
|
6
|
+
- Add guard classes to handle guard behaviour (`OutputEmptyGuard`, `OutputTypeGuard` and `RulesExhaustedGuard`)
|
7
|
+
- Add `optional:` keywords to most dsl (`attribute`, `collection`, `any`, `link`)
|
8
|
+
- Add `Formatter` class to handle formatting of the `Constructable#to_s`
|
9
|
+
- Add behaviour to strip leading dot (`.`) or plus (`+`) from `+%<var>` if `var` is nil, fixing weird media types
|
10
|
+
- Add behaviour to remove format variable values if format variable is not present, fixing warnings
|
11
|
+
- Add `inspect` for most public classes
|
12
|
+
- Add second argument for type or scheme to `any` dsl, mimicking `collection`
|
13
|
+
- Add tests for most dsl, common permutations
|
14
|
+
- Rename `force` to `expected_type`
|
15
|
+
- Remove `format_view` behaviour where it adds a dot (`.`) if a view is present
|
16
|
+
- Remove special iteration behaviour for `Links` (`link` dsl), allowing them to be optional, or non-exhaustive
|
17
|
+
- Raise error if `self.base_format` is not available at time of `Dsl.media_type` call
|
18
|
+
- Fix `expected_type` guard for arrays, nil, or arrays with nil.
|
19
|
+
|
1
20
|
# 0.4.1
|
2
21
|
|
3
22
|
- Use strings for `:_links`, matching the other validation keys
|
data/Gemfile.lock
CHANGED
@@ -1,44 +1,44 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
media_types (0.
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: https://rubygems.org/
|
8
|
-
specs:
|
9
|
-
ansi (1.5.0)
|
10
|
-
awesome_print (1.8.0)
|
11
|
-
builder (3.2.3)
|
12
|
-
docile (1.3.1)
|
13
|
-
json (2.1.0)
|
14
|
-
minitest (5.11.3)
|
15
|
-
minitest-ci (3.4.0)
|
16
|
-
minitest (>= 5.0.6)
|
17
|
-
minitest-reporters (1.3.4)
|
18
|
-
ansi
|
19
|
-
builder
|
20
|
-
minitest (>= 5.0)
|
21
|
-
ruby-progressbar
|
22
|
-
rake (10.5.0)
|
23
|
-
ruby-progressbar (1.10.0)
|
24
|
-
simplecov (0.16.1)
|
25
|
-
docile (~> 1.1)
|
26
|
-
json (>= 1.8, < 3)
|
27
|
-
simplecov-html (~> 0.10.0)
|
28
|
-
simplecov-html (0.10.2)
|
29
|
-
|
30
|
-
PLATFORMS
|
31
|
-
x64-mingw32
|
32
|
-
|
33
|
-
DEPENDENCIES
|
34
|
-
awesome_print
|
35
|
-
bundler (~> 1.16)
|
36
|
-
media_types!
|
37
|
-
minitest (~> 5.0)
|
38
|
-
minitest-ci
|
39
|
-
minitest-reporters
|
40
|
-
rake (~> 10.0)
|
41
|
-
simplecov
|
42
|
-
|
43
|
-
BUNDLED WITH
|
44
|
-
1.16.4
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
media_types (0.5.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ansi (1.5.0)
|
10
|
+
awesome_print (1.8.0)
|
11
|
+
builder (3.2.3)
|
12
|
+
docile (1.3.1)
|
13
|
+
json (2.1.0)
|
14
|
+
minitest (5.11.3)
|
15
|
+
minitest-ci (3.4.0)
|
16
|
+
minitest (>= 5.0.6)
|
17
|
+
minitest-reporters (1.3.4)
|
18
|
+
ansi
|
19
|
+
builder
|
20
|
+
minitest (>= 5.0)
|
21
|
+
ruby-progressbar
|
22
|
+
rake (10.5.0)
|
23
|
+
ruby-progressbar (1.10.0)
|
24
|
+
simplecov (0.16.1)
|
25
|
+
docile (~> 1.1)
|
26
|
+
json (>= 1.8, < 3)
|
27
|
+
simplecov-html (~> 0.10.0)
|
28
|
+
simplecov-html (0.10.2)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
x64-mingw32
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
awesome_print
|
35
|
+
bundler (~> 1.16)
|
36
|
+
media_types!
|
37
|
+
minitest (~> 5.0)
|
38
|
+
minitest-ci
|
39
|
+
minitest-reporters
|
40
|
+
rake (~> 10.0)
|
41
|
+
simplecov
|
42
|
+
|
43
|
+
BUNDLED WITH
|
44
|
+
1.16.4
|
data/README.md
CHANGED
@@ -1,347 +1,379 @@
|
|
1
|
-
# MediaTypes
|
2
|
-
[](https://travis-ci.com/SleeplessByte/media-types-ruby)
|
3
|
-
[](https://badge.fury.io/rb/media_types)
|
4
|
-
[](http://opensource.org/licenses/MIT)
|
5
|
-
[](https://codeclimate.com/github/SleeplessByte/media-types-ruby/maintainability)
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'media_types'
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install media_types
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
By default there are no media types registered or defined, except for an abstract base type.
|
26
|
-
|
27
|
-
## Definition
|
28
|
-
You can define media types by inheriting from this base type, or create your own base type with a class method
|
29
|
-
`.base_format` that is used to create the final media type string by injecting formatted parameters:
|
30
|
-
|
31
|
-
- `%<type>s`: the type `media_type` received
|
32
|
-
- `%<version>s`: the version, defaults to `:current_version`
|
33
|
-
- `%<view>s`: the view, defaults to <empty>
|
34
|
-
- `%<suffix>s`: the suffix
|
35
|
-
|
36
|
-
```Ruby
|
37
|
-
require 'media_types'
|
38
|
-
|
39
|
-
class Venue < MediaTypes::Base
|
40
|
-
media_type 'venue', defaults: { suffix: :json, version: 2 }
|
41
|
-
|
42
|
-
validations do
|
43
|
-
attribute :name, String
|
44
|
-
collection :location do
|
45
|
-
attribute :latitude, Numeric
|
46
|
-
attribute :longitude, Numeric
|
47
|
-
attribute :altitude, AllowNil(Numeric)
|
48
|
-
end
|
49
|
-
|
50
|
-
link :self
|
51
|
-
link :route, allow_nil: true
|
52
|
-
|
53
|
-
version 1 do
|
54
|
-
attribute :name, String
|
55
|
-
attribute :coords, String
|
56
|
-
attribute :updated_at, String
|
57
|
-
|
58
|
-
link :self
|
59
|
-
end
|
60
|
-
|
61
|
-
view 'create' do
|
62
|
-
collection :location do
|
63
|
-
attribute :latitude, Numeric
|
64
|
-
attribute :longitude, Numeric
|
65
|
-
attribute :altitude, AllowNil(Numeric)
|
66
|
-
end
|
67
|
-
|
68
|
-
version 1 do
|
69
|
-
collection :location do
|
70
|
-
attribute :latitude, Numeric
|
71
|
-
attribute :longitude, Numeric
|
72
|
-
attribute :altitude, AllowNil(Numeric)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
registrations :venue_json do
|
79
|
-
view 'create', :create_venue
|
80
|
-
view 'index', :venue_urls
|
81
|
-
view 'collection', :venue_collection
|
82
|
-
|
83
|
-
versions [1,2]
|
84
|
-
|
85
|
-
suffix :json
|
86
|
-
suffix :xml
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.base_format
|
90
|
-
'application/vnd.mydomain.%<type>s.v%<version
|
91
|
-
end
|
92
|
-
end
|
93
|
-
```
|
94
|
-
|
95
|
-
## Schema Definitions
|
96
|
-
|
97
|
-
If you define a scheme using `current_scheme { }`, you may use any of the following dsl:
|
98
|
-
|
99
|
-
### `attribute`
|
100
|
-
|
101
|
-
Adds an attribute to the schema, if a +block+ is given, uses that to test against instead of +type+
|
102
|
-
|
103
|
-
| param | type | description |
|
104
|
-
|-------|------|-------------|
|
105
|
-
| key | `Symbol` | the attribute name |
|
106
|
-
| opts | `Hash` | options to pass to `Scheme` or `Attribute` |
|
107
|
-
| type | `Class`, `===`, Scheme | The type of the value, can be anything that responds to `===`, or scheme to use if no `&block` is given. Defaults to `String` without a `&block` and to Hash with a `&block`. |
|
108
|
-
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
end
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
MyMedia
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
# =>
|
305
|
-
|
306
|
-
Venue.
|
307
|
-
#
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
1
|
+
# MediaTypes
|
2
|
+
[](https://travis-ci.com/SleeplessByte/media-types-ruby)
|
3
|
+
[](https://badge.fury.io/rb/media_types)
|
4
|
+
[](http://opensource.org/licenses/MIT)
|
5
|
+
[](https://codeclimate.com/github/SleeplessByte/media-types-ruby/maintainability)
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'media_types'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install media_types
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
By default there are no media types registered or defined, except for an abstract base type.
|
26
|
+
|
27
|
+
## Definition
|
28
|
+
You can define media types by inheriting from this base type, or create your own base type with a class method
|
29
|
+
`.base_format` that is used to create the final media type string by injecting formatted parameters:
|
30
|
+
|
31
|
+
- `%<type>s`: the type `media_type` received
|
32
|
+
- `%<version>s`: the version, defaults to `:current_version`
|
33
|
+
- `%<view>s`: the view, defaults to <empty>
|
34
|
+
- `%<suffix>s`: the suffix
|
35
|
+
|
36
|
+
```Ruby
|
37
|
+
require 'media_types'
|
38
|
+
|
39
|
+
class Venue < MediaTypes::Base
|
40
|
+
media_type 'venue', defaults: { suffix: :json, version: 2 }
|
41
|
+
|
42
|
+
validations do
|
43
|
+
attribute :name, String
|
44
|
+
collection :location do
|
45
|
+
attribute :latitude, Numeric
|
46
|
+
attribute :longitude, Numeric
|
47
|
+
attribute :altitude, AllowNil(Numeric)
|
48
|
+
end
|
49
|
+
|
50
|
+
link :self
|
51
|
+
link :route, allow_nil: true
|
52
|
+
|
53
|
+
version 1 do
|
54
|
+
attribute :name, String
|
55
|
+
attribute :coords, String
|
56
|
+
attribute :updated_at, String
|
57
|
+
|
58
|
+
link :self
|
59
|
+
end
|
60
|
+
|
61
|
+
view 'create' do
|
62
|
+
collection :location do
|
63
|
+
attribute :latitude, Numeric
|
64
|
+
attribute :longitude, Numeric
|
65
|
+
attribute :altitude, AllowNil(Numeric)
|
66
|
+
end
|
67
|
+
|
68
|
+
version 1 do
|
69
|
+
collection :location do
|
70
|
+
attribute :latitude, Numeric
|
71
|
+
attribute :longitude, Numeric
|
72
|
+
attribute :altitude, AllowNil(Numeric)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
registrations :venue_json do
|
79
|
+
view 'create', :create_venue
|
80
|
+
view 'index', :venue_urls
|
81
|
+
view 'collection', :venue_collection
|
82
|
+
|
83
|
+
versions [1,2]
|
84
|
+
|
85
|
+
suffix :json
|
86
|
+
suffix :xml
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.base_format
|
90
|
+
'application/vnd.mydomain.%<type>s.v%<version>.s%<view>s+%<suffix>s'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
## Schema Definitions
|
96
|
+
|
97
|
+
If you define a scheme using `current_scheme { }`, you may use any of the following dsl:
|
98
|
+
|
99
|
+
### `attribute`
|
100
|
+
|
101
|
+
Adds an attribute to the schema, if a +block+ is given, uses that to test against instead of +type+
|
102
|
+
|
103
|
+
| param | type | description |
|
104
|
+
|-------|------|-------------|
|
105
|
+
| key | `Symbol` | the attribute name |
|
106
|
+
| opts | `Hash` | options to pass to `Scheme` or `Attribute` |
|
107
|
+
| type | `Class`, `===`, Scheme | The type of the value, can be anything that responds to `===`, or scheme to use if no `&block` is given. Defaults to `String` without a `&block` and to Hash with a `&block`. |
|
108
|
+
| optional: | `TrueClass`, `FalseClass` | if true, key may be absent, defaults to `false` |
|
109
|
+
| &block | `Block` | defines the scheme of the value of this attribute |
|
110
|
+
|
111
|
+
#### Add an attribute named foo, expecting a string
|
112
|
+
```Ruby
|
113
|
+
require 'media_types'
|
114
|
+
|
115
|
+
class MyMedia
|
116
|
+
include MediaTypes::Dsl
|
117
|
+
|
118
|
+
validations do
|
119
|
+
attribute :foo, String
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
MyMedia.valid?({ foo: 'my-string' })
|
124
|
+
# => true
|
125
|
+
```
|
126
|
+
|
127
|
+
#### Add an attribute named foo, expecting nested scheme
|
128
|
+
|
129
|
+
```Ruby
|
130
|
+
class MyMedia
|
131
|
+
include MediaTypes::Dsl
|
132
|
+
|
133
|
+
validations do
|
134
|
+
attribute :foo do
|
135
|
+
attribute :bar, String
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
MyMedia.valid?({ foo: { bar: 'my-string' }})
|
141
|
+
# => true
|
142
|
+
```
|
143
|
+
|
144
|
+
### `any`
|
145
|
+
Allow for any key. The `&block` defines the Schema for each value.
|
146
|
+
|
147
|
+
| param | type | description |
|
148
|
+
|-------|------|-------------|
|
149
|
+
| scheme | `Scheme`, `NilClass` | scheme to use if no `&block` is given |
|
150
|
+
| allow_empty: | `TrueClass`, `FalsClass` | if true, empty (no key/value present) is allowed |
|
151
|
+
| expected_type: | `Class`, | forces the validated value to have this type, defaults to `Hash`. Use `Object` if either `Hash` or `Array` is fine |
|
152
|
+
| &block | `Block` | defines the scheme of the value of this attribute |
|
153
|
+
|
154
|
+
#### Add a collection named foo, expecting any key with a defined value
|
155
|
+
```Ruby
|
156
|
+
class MyMedia
|
157
|
+
include MediaTypes::Dsl
|
158
|
+
|
159
|
+
validations do
|
160
|
+
collection :foo do
|
161
|
+
any do
|
162
|
+
attribute :bar, String
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
MyMedia.valid?({ foo: [{ anything: { bar: 'my-string' }, other_thing: { bar: 'other-string' } }] })
|
169
|
+
# => true
|
170
|
+
````
|
171
|
+
|
172
|
+
### `not_strict`
|
173
|
+
Allow for extra keys in the schema/collection even when passing `strict: true` to `#validate!`
|
174
|
+
|
175
|
+
#### Allow for extra keys in collection
|
176
|
+
|
177
|
+
```Ruby
|
178
|
+
class MyMedia
|
179
|
+
include MediaTypes::Dsl
|
180
|
+
|
181
|
+
validations do
|
182
|
+
collection :foo do
|
183
|
+
attribute :required, String
|
184
|
+
not_strict
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
MyMedia.valid?({ foo: [{ required: 'test', bar: 42 }] })
|
190
|
+
# => true
|
191
|
+
```
|
192
|
+
|
193
|
+
### `collection`
|
194
|
+
Expect a collection such as an array or hash. The `&block` defines the Schema for each item in that collection.
|
195
|
+
|
196
|
+
| param | type | description |
|
197
|
+
|-------|------|-------------|
|
198
|
+
| key | `Symbol` | key of the collection (same as `#attribute`) |
|
199
|
+
| scheme | `Scheme`, `NilClass`, `Class` | scheme to use if no `&block` is given or `Class` of each item in the |
|
200
|
+
| allow_empty: | `TrueClass`, `FalseClass` | if true, empty (no key/value present) is allowed |
|
201
|
+
| expected_type: | `Class`, | forces the validated value to have this type, defaults to `Array`. Use `Object` if either `Array` or `Hash` is fine. |
|
202
|
+
| optional: | `TrueClass`, `FalseClass` | if true, key may be absent, defaults to `false` |
|
203
|
+
| &block | `Block` | defines the scheme of the value of this attribute |
|
204
|
+
|
205
|
+
|
206
|
+
#### Collection with an array of string
|
207
|
+
```Ruby
|
208
|
+
class MyMedia
|
209
|
+
include MediaTypes::Dsl
|
210
|
+
|
211
|
+
validations do
|
212
|
+
collection :foo, String
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
MyMedia.valid?({ collection: ['foo', 'bar'] })
|
217
|
+
# => true
|
218
|
+
```
|
219
|
+
|
220
|
+
#### Collection with defined scheme
|
221
|
+
|
222
|
+
```Ruby
|
223
|
+
class MyMedia
|
224
|
+
include MediaTypes::Dsl
|
225
|
+
|
226
|
+
validations do
|
227
|
+
collection :foo do
|
228
|
+
attribute :required, String
|
229
|
+
attribute :number, Numeric
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
MyMedia.valid?({ foo: [{ required: 'test', number: 42 }, { required: 'other', number: 0 }] })
|
235
|
+
# => true
|
236
|
+
```
|
237
|
+
|
238
|
+
### `link`
|
239
|
+
|
240
|
+
Expect a link with a required `href: String` attribute
|
241
|
+
|
242
|
+
| param | type | description |
|
243
|
+
|-------|------|-------------|
|
244
|
+
| key | `Symbol` | key of the link (same as `#attribute`) |
|
245
|
+
| allow_nil: | `TrueClass`, `FalseClass` | if true, value may be nil |
|
246
|
+
| optional: | `TrueClass`, `FalseClass` | if true, key may be absent, defaults to `false` |
|
247
|
+
| &block | `Block` | defines the scheme of the value of this attribute, in addition to the `href` attribute |
|
248
|
+
|
249
|
+
#### Links as defined in HAL, JSON-Links and other specs
|
250
|
+
```Ruby
|
251
|
+
class MyMedia
|
252
|
+
include MediaTypes::Dsl
|
253
|
+
|
254
|
+
validations do
|
255
|
+
link :_self
|
256
|
+
link :image
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
MyMedia.valid?({ _links: { self: { href: 'https://example.org/s' }, image: { href: 'https://image.org/i' }} })
|
261
|
+
# => true
|
262
|
+
```
|
263
|
+
|
264
|
+
|
265
|
+
#### Link with extra attributes
|
266
|
+
```Ruby
|
267
|
+
class MyMedia
|
268
|
+
include MediaTypes::Dsl
|
269
|
+
|
270
|
+
validations do
|
271
|
+
link :image do
|
272
|
+
attribute :templated, TrueClass
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
MyMedia.valid?({ _links: { self: { href: 'https://example.org/s' }, image: { href: 'https://image.org/i' }} })
|
278
|
+
# => true
|
279
|
+
```
|
280
|
+
|
281
|
+
#### Link with extra attributes
|
282
|
+
```Ruby
|
283
|
+
class MyMedia
|
284
|
+
include MediaTypes::Dsl
|
285
|
+
|
286
|
+
validations do
|
287
|
+
link :image do
|
288
|
+
attribute :templated, TrueClass
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
MyMedia.valid?({ _links: { image: { href: 'https://image.org/{md5}', templated: true }} })
|
294
|
+
# => true
|
295
|
+
```
|
296
|
+
|
297
|
+
## Validation
|
298
|
+
If your type has a validations, you can now use this media type for validation:
|
299
|
+
|
300
|
+
```Ruby
|
301
|
+
Venue.valid?({
|
302
|
+
#...
|
303
|
+
})
|
304
|
+
# => true if valid, false otherwise
|
305
|
+
|
306
|
+
Venue.validate!({
|
307
|
+
# /*...*/
|
308
|
+
})
|
309
|
+
# => raises if it's not valid
|
310
|
+
```
|
311
|
+
|
312
|
+
If an array is passed, check the scheme for each value, unless the scheme is defined as expecting a hash:
|
313
|
+
```Ruby
|
314
|
+
expected_hash = Scheme.new(expected_type: Hash) { attribute(:foo) }
|
315
|
+
expected_object = Scheme.new { attribute(:foo) }
|
316
|
+
|
317
|
+
expected_hash.valid?({ foo: 'string' })
|
318
|
+
# => true
|
319
|
+
|
320
|
+
expected_hash.valid?([{ foo: 'string' }])
|
321
|
+
# => false
|
322
|
+
|
323
|
+
|
324
|
+
expected_object.valid?({ foo: 'string' })
|
325
|
+
# => true
|
326
|
+
|
327
|
+
expected_object.valid?([{ foo: 'string' }])
|
328
|
+
# => true
|
329
|
+
```
|
330
|
+
|
331
|
+
## Formatting for headers
|
332
|
+
Any media type object can be coerced in valid string to be used with `Content-Type` or `Accept`:
|
333
|
+
|
334
|
+
```Ruby
|
335
|
+
Venue.mime_type.to_s
|
336
|
+
# => "application/vnd.mydomain.venue.v2+json"
|
337
|
+
|
338
|
+
Venue.mime_type.version(1).to_s
|
339
|
+
# => "application/vnd.mydomain.venue.v1+json"
|
340
|
+
|
341
|
+
Venue.mime_type.version(1).suffix(:xml).to_s
|
342
|
+
# => "application/vnd.mydomain.venue.v1+xml"
|
343
|
+
|
344
|
+
Venue.mime_type.to_s(0.2)
|
345
|
+
# => "application/vnd.mydomain.venue.v2+json; q=0.2"
|
346
|
+
|
347
|
+
Venue.mime_type.collection.to_s
|
348
|
+
# => "application/vnd.mydomain.venue.v2.collection+json"
|
349
|
+
|
350
|
+
Venue.mime_type.view('active').to_s
|
351
|
+
# => "application/vnd.mydomain.venue.v2.active+json"
|
352
|
+
```
|
353
|
+
|
354
|
+
## Register in Rails or Rack
|
355
|
+
Define a `registrations` block on your media type, indicating the symbol for the base type (`registrations :symbol do`)
|
356
|
+
and inside use the registrations dsl to define which media types to register. `versions array_of_numbers` determines which versions,
|
357
|
+
`suffix name` adds a suffix, `type_alias name` adds an alias and `view name, symbol` adds a view.
|
358
|
+
|
359
|
+
As long as `action_dispatch` is available, you can register the mime type with `action_dispatch/http/mime_type`:
|
360
|
+
```Ruby
|
361
|
+
Venue.register
|
362
|
+
# => Mime type is now available using the symbol, or lookup the actual mimetype
|
363
|
+
```
|
364
|
+
|
365
|
+
You can do this in the `mime_types` initializer, or anywhere before your controllers are instantiated. Yes, the symbol
|
366
|
+
(by default `<type>_v<version>_<suffix>`) can now be used in your `format` blocks, or as extension in the url.
|
367
|
+
|
368
|
+
## Development
|
369
|
+
|
370
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can
|
371
|
+
also run `bin/console` for an interactive prompt that will allow you to experiment.
|
372
|
+
|
373
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
374
|
+
version number in `version.rb`, call `bundle exec rake release` to create a new git tag, push git commits and tags, and
|
375
|
+
push the `.gem` file to rubygems.org.
|
376
|
+
|
377
|
+
## Contributing
|
378
|
+
|
379
|
+
Bug reports and pull requests are welcome on GitHub at [SleeplessByte/media-types-ruby](https://github.com/SleeplessByte/media-types-ruby)
|