Skip to content

booch/dry-data

 
 

Repository files navigation

Dry::Data Join the chat at https://gitter.im/dryrb/chat

Gem Version Build Status Dependency Status Code Climate Documentation Status

A simple type-system for Ruby respecting ruby's built-in coercion mechanisms.

Installation

Add this line to your application's Gemfile:

gem 'dry-data'

And then execute:

$ bundle

Or install it yourself as:

$ gem install dry-data

Why?

Unlike seemingly similar libraries like virtus, attrio, fast_attrs, attribs etc. Dry::Data provides you an interface to explicitly specify data types you want to use in your application domain which gives you type-safety and simple coercion mechanism using built-in coercion methods on the kernel.

Main difference is that Dry::Data is not designed to handle all kinds of complex coercions that are typically required when dealing with, let's say, form params in a web application. Its primary focus is to allow you to specify the exact shape of the custom application data types to avoid silly bugs that are often hard to debug (NoMethodError: undefined method size' for nil:NilClass` anyone?).

Usage

Primary usage of this library is defining domain data types that your application will work with. The interface consists of lower-level type definitions and a higher-level virtus-like interface for defining structs.

Accessing built-in types

Coercible types using kernel coercion methods:

  • string
  • int
  • float
  • decimal
  • array
  • hash

Non-coercible:

  • nil
  • true
  • false
  • date
  • date_time
  • time

More types will be added soon.

Types are grouped under 4 categories:

  • default: pass-through without any checks
  • strict - doesn't coerce and checks the input type against the primitive class
  • coercible - tries to coerce and raises type-error if it failed
  • maybe - accepts either a nil or something else
# default passthrough category
float = Dry::Data["float"]

float[3.2] # => 3.2
float["3.2"] # "3.2"

# strict type-check category
int = Dry::Data["strict.int"]

int[1] # => 1
int['1'] # => raises TypeError

# coercible type-check group
string = Dry::Data["coercible.string"]
array = Dry::Data["coercible.array"]

string[:foo] # => 'foo'
array[:foo] # => [:foo]

Optional types

All built-in types have their optional versions too, you can access them under "maybe.strict" and "maybe.coercible" categories:

maybe_int = Dry::Data["maybe.strict.int"]

maybe_int[nil] # None
maybe_int[123] # Some(123)

maybe_coercible_float = Dry::Data["maybe.coercible.float"]

maybe_int[nil] # None
maybe_int['12.3'] # Some(12.3)

You can define your own optional types too:

maybe_string = Dry::Data["nil"] | Dry::Data["string"]

maybe_string[nil]
# => None

maybe_string[nil].fmap(&:upcase)
# => None

maybe_string['something']
# => Some('something')

maybe_string['something'].fmap(&:upcase)
# => Some('SOMETHING')

maybe_string['something'].fmap(&:upcase).value
# => "SOMETHING"

Defining a struct

class User < Dry::Data::Struct
  attribute :name, "maybe.coercible.string"
  attribute :age, "coercible.int"
end

# becomes available like any other type
user_type = Dry::Data["user"]

user = user_type[name: nil, age: '21']

user.name # None
user.age # 21

user = user_type[name: 'Jane', age: '21']

user.name # => Some("Jane")
user.age # => 21

WIP

This is early alpha with a rough plan to:

  • Add constrained types (ie a string with a strict length, a number with a strict range etc.)
  • Benchmark against other libs and make sure it's fast enough

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 tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/dryrb/dry-data.

About

Simple type-system for Ruby

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 99.4%
  • Shell 0.6%