RiceBubble
Simple serialization with a sprinkling of type safety. Part of your complete breakfast.
Installation
Install the gem and add to the application's Gemfile by executing:
$ bundle add rice_bubble
If bundler is not being used to manage dependencies, install the gem by executing:
$ gem install rice_bubble
Usage
Create a subclass of RiceBubble::Serializer
and add some attributes:
class CharacterSerializer < RiceBubble::Serializer
attributes(
name: string,
player_name: optional(string),
class: enum('fighter', 'wizard', 'thief'),
stats: object(
strength: integer,
dexterity: integer,
constitution: integer,
intelligence: integer,
wisdom: integer,
charisma: integer,
)
)
end
Then you can use the new serializer to convert your data to a JSON-friendly representation:
json = CharacterSerializer.new(my_character).call # => { name: "...", ... }
Note: you can also use CharacterSerializer.call(my_character)
.
Attribute types
Name | Expects | Options | Example |
---|---|---|---|
any |
any of the specified types | array of attribute types | any(string, integer) |
boolean |
true or false |
boolean |
|
date |
Date or #to_date |
date |
|
enum |
matching string | array of string values | enum('red', 'blue', 'green') |
integer |
Integer or #to_i |
max , min |
integer(min: 3, max: 20) |
literal |
exactly matching value | literal | literal('foo') |
number |
Numeric |
max , min |
number(min: 3, max: 20) |
object |
Object or Hash |
hash of object names and attribute types | object(name: string, age: integer) |
optional |
value or nil |
attribute type | optional(string) |
serialized |
Object or Hash |
Serializer class |
serialized(SkillSerializer) |
string |
String or #to_s |
max , min , format |
string(min: 3, max: 20, format: /\A[a-z]+\z/i) |
time |
Time or #to_time |
time |
In this way, you can recursively build up quite complex nested structures of attributes in your serializer.
optional
All attributes are required unless marked as optional. You can either do this with
the optional
attribute type, or by appending .optional
to the attribute definition.
That is, the following are equivalent:
optional(string(min: 3))
string(min: 3).optional
Implementing your own attribute types
The attribute types are looked up automatically in the namespace
RiceBubble::Attributes
. Any subclass of RiceBubble::Attributes::Base
located there
will automatically be found by the serializer.
class RiceBubble::Serializer::Wrap < RiceBubble::Attributes::Base
def initialize(with: %w([ ]), &)
super(&)
@before, @after = with
end
def coerce(value)
"#{before}#{value}#{after}"
end
end
class WrappingSerializer < RiceBubble::Serializer
attributes(
name: wrap(with: %w({ }))
)
end
WrappingSerializer.call({ name: 'Spicy Beef' }) # => { name: '{Spicy Beef}' }
Fetching values from an object
By default, attributes know how to fetch their values from the object being serialized by either (in this order):
- invoking an instance method with the same name on the serializer; or
- invoking an instance method with the same name on the object; or
- looking up a hash key on the object
class FullNameSerializer
attributes(
full_name: string
)
def full_name
[object.first_name, object.last_name].join(' ')
end
end
You can also change how a value is retrieved by passing a block to the attribute:
class FullNameSerializer
attributes(
full_name: string { |o, _| [o.first_name, o.last_name].join(' ') }
)
end
The block takes two values: the object being serialized, and (optionally) the name of the key being retrieved.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitLab at https://gitlab.com/fauxparse/rice_bubble. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the RiceBubble project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.