Foraneus

Foraneus allows to:

  • parse data coming from external sources (like an HTTP request).
  • convert data back to a raw representation suitable for being used at the outside, like an HTML form.

No matter which source of data is fed into Foraneus (external or internal), any instance can return raw and parsed data.

Basic usage

  • Declaration:
  class MyForm < Foraneus
    integer :delay
    float :duration
  end
  • From the outside:
  form = MyForm.parse(:delay => '5', :duration => '2.14')
  form.delay    # => 5
  form[:delay]  # => '5'
  form.data   # => { :delay => 5, :duration => 2.14 }
  form[]      # => { :delay => '5', :duration => '2.14' }
  • From the inside:
  form = MyForm.raw(:delay => 5, :duration => 2.14)
  form.delay    # => 5
  form[:delay]  # => '5'
  form.data   # => { :delay => 5, :duration => 2.14 }
  form[]      # => { :delay => '5', :duration => '2.14' }

Declaration

Declare source classes by inheriting from Foraneus base class.

  class MyForm < Foraneus
    field :delay, SomeCustomConverter.new
    float :duration
  end

Fields are declared in two ways:

  • calling .field
  • calling a shortcut method, like .float

There are handy methods for any of the built-in converters: boolean, date, decimal, float, integer, noop, and string.

When no converter is passed to .field, Foraneus::Converters::Noop is assigned to the declared field.

Instantiation

Foraneus instances can be obtained by calling two methods: parse and raw.

Use .parse when:

  • data is coming from outside of the system, like an HTTP request.

Use .raw when:

  • data is coming from the inside of the system, like a business layer.

Converters

Converters have two interrelated responsibilities:

  • Parse data, like the string "3,000", into an object, like 3_000.
  • Serialize data, like integer 3_000, into string "3,000"

A converter is simply an object that responds to #parse(s), #raw(v), and #opts methods.

When #parse(s) raises a StandardError exception, or any of its descendants, the exception is rescued and a Foraneus::Error instance is added to Foraneus#errors map.

#opts should return the opts hash used to instantiate the converter.

Built-in converters:

  • Boolean
  • Date
  • Decimal
  • Float
  • Integer
  • Noop
  • String

Validations

Foraneus only validates that external data can be converted to the specified types. Smart validations, like date range inclusion, are out of the scope of this gem.

#valid? and #errors are handy methods that tell whether a Foraneus instance is valid or not.

Valid instance:

  form.valid?     # => true
  form[:errors]   # => {}

Invalid one:

  form = MyForm.parse(:delay => 'INVALID')

  form.valid?                     # => false

  form[:errors][:delay].key       # => 'ArgumentError'
  form[:errors][:delay].message   # => 'invalid value for Integer(): "INVALID"'

#errors is a map in which keys correspond to field names, and values are instances of Foraneus::Error.

The name of the exception raised by #parse is the error's key attribute, and the exception's message is added to the error's message attribute.

Data coming from the inside is assumed to be valid, so .raw won't return an instance having errors neither being invalid.

Required fields

Fields can be declared as required.

  class MyForm < Foraneus
    integer :delay, :required => true
  end

If an external value is not fed into a required field, an error with key 'KeyError' will be assigned.

  form = MyForm.parse

  form.valid?                       # => false

  form[:errors][:delay].key         # => 'KeyError'
  form[:errors][:delay].message     # => 'required parameter not found: "delay"'

Blank values

By default, any blank value is treated as nil.

  MyForm = Class.new(Foraneus) { string :name }

  MyForm.parse(:name => '').name
  # => nil

This behaviour can be modified by setting opt blanks_as_nil to false.

  MyForm = Class.new(Foraneus) { string :name, :blanks_as_nil => false }

  MyForm.parse(:name => '').name
  # => ''

Default values

Define fields with default values:

  MyForm = Class.new(Foraneus) { string :name, :default => 'Alice' }

Parse data from the ouside:

  form = MyForm.parse

  form.name             # => 'Alice'
  form[:name]           # => nil, data from the outside don't include any value

Convert values back from the inside:

  form = MyForm.raw

  form[:name]           # => 'Alice'
  form.name             # => nil, data from the inside don't include any value

Installation

  • Install foraneus as a gem.

    gem install foraneus
    

Running tests

Tests are written in RSpec. To run them all just execute the following from your command line:

  rspec

Code documentation

Documentation is written in Yard. To see it in a browser, execute this command:

  yard server --reload

Then point the browser to http://localhost:8808/.

Badges

Build Status Code Climate

License

This software is licensed under the LGPL license.