Skip to content

Commit

Permalink
Attribute type aliases with Shale::Type.register and Shale::Type.look…
Browse files Browse the repository at this point in the history
…up (#44)

* Attribute type aliases with Shale::Type.register and Shale::Type.lookup

* Changes from CR
  • Loading branch information
admtnnr authored Oct 9, 2024
1 parent 8ec3be6 commit ea29fda
Show file tree
Hide file tree
Showing 24 changed files with 421 additions and 192 deletions.
174 changes: 104 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,17 @@ $ gem install shale
require 'shale'

class Address < Shale::Mapper
attribute :city, Shale::Type::String
attribute :street, Shale::Type::String
attribute :zip, Shale::Type::String
attribute :city, :string
attribute :street, :string
attribute :zip, :string
end

class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :married, Shale::Type::Boolean, default: -> { false }
attribute :hobbies, Shale::Type::String, collection: true
attribute :first_name, :string
attribute :last_name, :string
attribute :age, :integer
attribute :married, :boolean, default: -> { false }
attribute :hobbies, :string, collection: true
attribute :address, Address
end
```
Expand Down Expand Up @@ -443,8 +443,8 @@ By default keys are named the same as attributes. To use custom keys use:

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string

json do
map 'firstName', to: :first_name
Expand All @@ -457,8 +457,8 @@ end

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string

yaml do
map 'firstName', to: :first_name
Expand All @@ -471,8 +471,8 @@ end

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string

toml do
map 'firstName', to: :first_name
Expand All @@ -489,8 +489,8 @@ to `:first_name` attribute and the second column to `:last_name`.

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string

csv do
map 'firstName', to: :first_name
Expand All @@ -503,8 +503,8 @@ end

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string

hsh do
map 'firstName', to: :first_name
Expand All @@ -519,9 +519,9 @@ XML is more complicated format than JSON or YAML. To map elements, attributes an

```ruby
class Address < Shale::Mapper
attribute :street, Shale::Type::String
attribute :city, Shale::Type::String
attribute :zip, Shale::Type::String
attribute :street, :string
attribute :city, :string
attribute :zip, :string

xml do
map_content to: :street
Expand All @@ -531,10 +531,10 @@ class Address < Shale::Mapper
end

class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :hobbies, Shale::Type::String, collection: true
attribute :first_name, :string
attribute :last_name, :string
attribute :age, :integer
attribute :hobbies, :string, collection: true
attribute :address, Address

xml do
Expand Down Expand Up @@ -573,15 +573,15 @@ You can use `cdata: true` option on `map_element` and `map_content` to handle CD

```ruby
class Address < Shale::Mapper
attribute :content, Shale::Type::String
attribute :content, :string

xml do
map_content to: :content, cdata: true
end
end

class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :first_name, :string
attribute :address, Address

xml do
Expand All @@ -607,9 +607,9 @@ To map namespaced elements and attributes use `namespace` and `prefix` propertie

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :first_name, :string
attribute :last_name, :string
attribute :age, :integer

xml do
root 'person'
Expand All @@ -634,11 +634,11 @@ explicitly declare it on `map_attribute`).

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :middle_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :hobby, Shale::Type::String
attribute :first_name, :string
attribute :middle_name, :string
attribute :last_name, :string
attribute :age, :integer
attribute :hobby, :string

xml do
root 'person'
Expand Down Expand Up @@ -674,9 +674,9 @@ For CSV the default is to render `nil` elements.

```ruby
class Person < Shale::Mapper
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :first_name, :string
attribute :last_name, :string
attribute :age, :integer

json do
map 'first_name', to: :first_name, render_nil: true
Expand Down Expand Up @@ -724,9 +724,9 @@ class Base < Shale::Mapper
end

class Person < Base
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :first_name, :string
attribute :last_name, :string
attribute :age, :integer

json do
# override default from Base class
Expand All @@ -743,8 +743,8 @@ end

```ruby
class Person < Base
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string

json do
render_nil false
Expand All @@ -763,9 +763,9 @@ you can use methods to do so:

```ruby
class Person < Shale::Mapper
attribute :hobbies, Shale::Type::String, collection: true
attribute :street, Shale::Type::String
attribute :city, Shale::Type::String
attribute :hobbies, :string, collection: true
attribute :street, :string
attribute :city, :string

json do
map 'hobbies', using: { from: :hobbies_from_json, to: :hobbies_to_json }
Expand Down Expand Up @@ -854,7 +854,7 @@ You can also pass a `context` object that will be available in extractor/generat

```ruby
class Person < Shale::Mapper
attribute :password, Shale::Type::String
attribute :password, :string

json do
map 'password', using: { from: :password_from_json, to: :password_to_json }
Expand Down Expand Up @@ -884,7 +884,7 @@ If you want to work on multiple elements at a time you can group them using `gro

```ruby
class Person < Shale::Mapper
attribute :name, Shale::Type::String
attribute :name, :string

json do
group from: :name_from_json, to: :name_to_json do
Expand Down Expand Up @@ -935,12 +935,12 @@ To delegate fields to child complex types you can use `receiver: :child` declara

```ruby
class Address < Shale::Mapper
attribute :city, Shale::Type::String
attribute :street, Shale::Type::String
attribute :city, :string
attribute :street, :string
end

class Person < Shale::Mapper
attribute :name, Shale::Type::String
attribute :name, :string
attribute :address, Address

json do
Expand Down Expand Up @@ -1060,8 +1060,8 @@ names and shouldn't be included in the returned collection. It also accepts all

```ruby
class Person
attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string
end

people = Person.from_csv(<<~DATA, headers: true, col_sep: '|')
Expand Down Expand Up @@ -1091,10 +1091,10 @@ with NaN values in JSON:

```ruby
class Person
attribute :age, Shale::Type::Float
attribute :age, :float
end

person = Person.from_jsom('{"age": NaN}', allow_nan: true)
person = Person.from_json('{"age": NaN}', allow_nan: true)

# =>
#
Expand All @@ -1115,7 +1115,7 @@ It's possible to override an attribute method to change its output:

```ruby
class Person < Shale::Mapper
attribute :gender, Shale::Type::String
attribute :gender, :string

def gender
if super == 'm'
Expand Down Expand Up @@ -1160,15 +1160,15 @@ end
class AddressMapper < Shale::Mapper
model Address

attribute :street, Shale::Type::String
attribute :city, Shale::Type::String
attribute :street, :string
attribute :city, :string
end

class PersonMapper < Shale::Mapper
model Person

attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :first_name, :string
attribute :last_name, :string
attribute :address, AddressMapper
end

Expand Down Expand Up @@ -1208,12 +1208,21 @@ PersonMapper.to_json(person, pretty: true)

Shale supports these types out of the box:

- `Shale::Type::Boolean`
- `Shale::Type::Date`
- `Shale::Type::Float`
- `Shale::Type::Integer`
- `Shale::Type::String`
- `Shale::Type::Time`
- `:boolean` (`Shale::Type::Boolean`)
- `:date` (`Shale::Type::Date`)
- `:float` (`Shale::Type::Float`)
- `:integer` (`Shale::Type::Integer`)
- `:string` (`Shale::Type::String`)
- `:time` (`Shale::Type::Time`)

The symbol type alias and the type class are interchangeable:

```ruby
class Person < Shale::Mapper
attribute :age, Shale::Type::Integer
# attribute :age, :integer
end
```

### Writing your own type

Expand All @@ -1229,6 +1238,31 @@ class MyIntegerType < Shale::Type::Value
end
```

Then you can use it in your model:

```ruby
class Person < Shale::Mapper
attribute :age, MyIntegerType
end
```

You can also register your own type with a symbol alias if you
intend to use it often.

```ruby
require 'shale/type'

Shale::Type.register(:my_integer, MyIntegerType)
```

Then you can use it like this:

```ruby
class Person < Shale::Mapper
attribute :age, :my_integer
end
```

### Adapters

Shale uses adapters for parsing and generating documents.
Expand Down Expand Up @@ -1381,10 +1415,10 @@ require 'shale/schema'
class PersonMapper < Shale::Mapper
model Person

attribute :first_name, Shale::Type::String
attribute :last_name, Shale::Type::String
attribute :address, Shale::Type::String
attribute :age, Shale::Type::Integer
attribute :first_name, :string
attribute :last_name, :string
attribute :address, :string
attribute :age, :integer

json do
properties max_properties: 5
Expand Down
1 change: 1 addition & 0 deletions lib/shale.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

require_relative 'shale/mapper'
require_relative 'shale/adapter/json'
require_relative 'shale/type'
require_relative 'shale/type/boolean'
require_relative 'shale/type/date'
require_relative 'shale/type/float'
Expand Down
12 changes: 12 additions & 0 deletions lib/shale/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ class IncorrectMappingArgumentsError < ShaleError
class NotAShaleMapperError < ShaleError
end

# Error for registering class that is not a valid Type::Value
#
# @api private
class NotATypeValueError < ShaleError
end

# Error for using unknown symbol type
#
# @api private
class UnknownTypeError < ShaleError
end

# Raised when receiver attribute is not defined
#
# @api private
Expand Down
Loading

0 comments on commit ea29fda

Please sign in to comment.