granola 0.10.0 → 0.10.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6b87c4322ddf8aa97dd49c26607172fe2119d681
4
- data.tar.gz: 959742990805ff8890d821177d1c70c5804e5c18
3
+ metadata.gz: 83004a0de438c36e72d1b6e9a42a4247532d54ac
4
+ data.tar.gz: f393e6a7bc0b330978a89dffdf6bb39aca568716
5
5
  SHA512:
6
- metadata.gz: 4cbdca00522d796177eaa836f822355fbda7959033b71a1eefaea8ceac9dcf48517fd8395c628cf3ab137fa30433d8e66e7a063eb74a42c88be8560caac63251
7
- data.tar.gz: 05a3665f2b5e13385c014de61e6a213520a339ae162159ca4e86f5e753dc506c2ad2d02016119aa016198ae25b5fa56ffac28ec9e6f5ee5f0f08f1f208ba4240
6
+ metadata.gz: 8b8767a91cfafb4fcbe99475988ae6a4de500eb8c71f08acde98833ebbd1ad7a1805d5b79aa8b43770b45cdd7b03b9517e8452d9c004a29c40b473db9dc4e041
7
+ data.tar.gz: f97a298c5cbfa89d5ff3d7358fa803347c226f247113174ef28439f39bda9d2cae5505e092cde5d5e03a08e4edd6fa730f7b06ada2adac8d19a315a8efcc28e1
@@ -0,0 +1,37 @@
1
+ require "granola/serializer"
2
+ require "json"
3
+
4
+ module Granola
5
+ class << self
6
+ # Public: Get/Set a Proc that takes an Object and a Hash of options and
7
+ # returns a JSON String.
8
+ #
9
+ # The default implementation uses the standard library's JSON module, but
10
+ # you're welcome to swap it out.
11
+ #
12
+ # Example:
13
+ #
14
+ # require "yajl"
15
+ # Granola.json = ->(obj, **opts) { Yajl::Encoder.encode(obj, opts) }
16
+ attr_accessor :json
17
+ end
18
+
19
+ if defined?(MultiJson)
20
+ self.json = MultiJson.method(:dump)
21
+ else
22
+ self.json = JSON.method(:generate)
23
+ end
24
+
25
+ class Serializer
26
+ MIME_TYPES[:json] = "application/json".freeze
27
+
28
+ # Public: Generate the JSON String.
29
+ #
30
+ # **options - Any options to be passed to the `Granola.json` Proc.
31
+ #
32
+ # Returns a String.
33
+ def to_json(**options)
34
+ Granola.json.(data, options)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,85 @@
1
+ module Granola
2
+ # A Serializer describes how to serialize a certain type of object, by
3
+ # declaring the structure of JSON objects.
4
+ class Serializer
5
+ attr_reader :object
6
+
7
+ # Public: Map of the default MIME type for each given type of serialization
8
+ # for this object. If your API returns a different MIME type for your
9
+ # responses (for example, `application/vnd.company+json`) you should replace
10
+ # it here.
11
+ MIME_TYPES = {}
12
+
13
+ # Public: Instantiates a list serializer that wraps around an iterable of
14
+ # objects of the type expected by this serializer class.
15
+ #
16
+ # Example:
17
+ #
18
+ # serializer = PersonSerializer.list(people)
19
+ # serializer.to_json
20
+ #
21
+ # Returns a Granola::List.
22
+ def self.list(ary, *args)
23
+ List.new(ary, *args, with: self)
24
+ end
25
+
26
+ # Public: Initialize the serializer with a given object.
27
+ #
28
+ # object - The domain model that we want to serialize into JSON.
29
+ def initialize(object)
30
+ @object = object
31
+ end
32
+
33
+ # Public: Returns a primitive Object that can be serialized into JSON,
34
+ # meaning one of `nil`, `true`, `false`, a String, a Numeric, an Array of
35
+ # primitive objects, or a Hash with String keys and primitive objects as
36
+ # values.
37
+ #
38
+ # Raises NotImplementedError unless you override in subclasses.
39
+ def data
40
+ fail NotImplementedError
41
+ end
42
+
43
+ # Internal: Returns the MIME type generated by this serializer.
44
+ #
45
+ # type - A Symbol describing the expected mime type.
46
+ #
47
+ # Returns a String.
48
+ def mime_type(type = :json)
49
+ MIME_TYPES.fetch(type)
50
+ end
51
+ end
52
+
53
+ # Internal: The List serializer provides an interface for serializing lists of
54
+ # objects, wrapping around a specific serializer. The preferred API for this
55
+ # is to use `Granola::Serializer.list`.
56
+ #
57
+ # Example:
58
+ #
59
+ # serializer = Granola::List.new(people, with: PersonSerializer)
60
+ # serializer.to_json
61
+ #
62
+ # You should use Serializer.list instead of this class.
63
+ class List < Serializer
64
+ # Internal: Get the serializer class to use for each item of the list.
65
+ attr_reader :item_serializer
66
+
67
+ # Public: Instantiate a new list serializer.
68
+ #
69
+ # list - An Array-like structure.
70
+ # *args - Any other arguments that the item serializer takes.
71
+ #
72
+ # Keywords:
73
+ # with: The subclass of Granola::Serializer to use when serializing
74
+ # specific elements in the list.
75
+ def initialize(list, *args, with: serializer)
76
+ @item_serializer = with
77
+ @list = list.map { |obj| @item_serializer.new(obj, *args) }
78
+ end
79
+
80
+ # Public: Returns an Array of Hashes that can be serialized into JSON.
81
+ def data
82
+ @list.map(&:data)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,56 @@
1
+ require "granola/serializer"
2
+
3
+ module Granola
4
+ module Util
5
+ # Public: Returns the serializer object for rendering a specific object. The
6
+ # class will attempt to be inferred based on the class of the passed object,
7
+ # but a specific serializer can be passed via a keyword argument `with`.
8
+ #
9
+ # object - The Object to serialize.
10
+ #
11
+ # Keywords
12
+ # with: A specific serializer class to use. If this is `nil`,
13
+ # `Util.serializer_class_for` will be used to infer the serializer
14
+ # class. This is ignored if `object` is already a Serializer.
15
+ #
16
+ # Raises NameError if no specific serializer is provided and we fail to
17
+ # infer one for this object.
18
+ #
19
+ # Returns an instance of a Granola::Serializer subclass.
20
+ def self.serializer_for(object, with: nil)
21
+ return object if Granola::Serializer === object
22
+ serializer_class = with || serializer_class_for(object)
23
+ method = object.respond_to?(:to_ary) ? :list : :new
24
+ serializer_class.send(method, object)
25
+ end
26
+
27
+ # Internal: Infers the name of a serializer based on the class of the passed
28
+ # object. The pattern is the Object's class + "Serializer". So
29
+ # `PersonSerializer` for `Person`.
30
+ #
31
+ # object - An object of a class with a matching serializer.
32
+ #
33
+ # Raises NameError if no matching class exists.
34
+ # Returns a Class.
35
+ def self.serializer_class_for(object)
36
+ object = object.respond_to?(:to_ary) ? object.to_ary.fetch(0, nil) : object
37
+ name = object.class.name
38
+ Object.const_get("%sSerializer" % name)
39
+ rescue NameError
40
+ case object
41
+ when NilClass, TrueClass, FalseClass, Numeric, String
42
+ PrimitiveTypesSerializer
43
+ else
44
+ raise
45
+ end
46
+ end
47
+
48
+ # Internal: Null serializer that transparently handles rendering primitive
49
+ # types.
50
+ class PrimitiveTypesSerializer < Granola::Serializer
51
+ def data
52
+ object
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,3 +1,3 @@
1
1
  module Granola
2
- VERSION = "0.10.0"
2
+ VERSION = "0.10.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: granola
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicolas Sanguinetti
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-16 00:00:00.000000000 Z
11
+ date: 2015-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cutest
@@ -49,7 +49,10 @@ files:
49
49
  - README.md
50
50
  - lib/granola.rb
51
51
  - lib/granola/caching.rb
52
+ - lib/granola/json.rb
52
53
  - lib/granola/rack.rb
54
+ - lib/granola/serializer.rb
55
+ - lib/granola/util.rb
53
56
  - lib/granola/version.rb
54
57
  homepage: http://github.com/foca/granola
55
58
  licenses: