Skip to content

Add support for dry-types #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.

## [0.4.1] - 2020-07-12
### Added
- Plugin for gem `dry-types`

## [0.4.0] - 2020-07-12
### Added
- Attribue Definition DSL
Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,20 @@ GEM
rubocop-rake (= 0.5.1)
rubocop-rspec (= 1.42.0)
ast (2.4.1)
coderay (1.1.3)
concurrent-ruby (1.1.6)
diff-lcs (1.4.4)
docile (1.3.2)
i18n (1.8.3)
concurrent-ruby (~> 1.0)
method_source (1.0.0)
minitest (5.14.1)
parallel (1.19.2)
parser (2.7.1.4)
ast (~> 2.4.1)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
qonfig (0.24.1)
rack (2.2.3)
rainbow (3.0.0)
Expand Down Expand Up @@ -91,6 +96,7 @@ PLATFORMS
DEPENDENCIES
armitage-rubocop (~> 0.87)
bundler (~> 2.1)
pry
rake (~> 13.0)
rspec (~> 3.9)
simplecov (~> 0.18)
Expand Down
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ require 'smart_core/initializer'
- [Initialization extension](#initialization-extension)
- [Plugins](#plugins)
- [thy-types](#plugin-thy-types)
- [dry-types](#plugin-dry-types)
- [Roadmap](#roadmap)
- [How to run tests](#how-to-run-tests)

Expand Down Expand Up @@ -280,13 +281,57 @@ User.new('daiver', '[email protected]', { admin: true, age: 19 })
User.new('daiver', '[email protected]', { age: 17 })
# SmartCore::Initializer::ThyTypeValidationError

# invaldi case (invalid nickname)
# invalid case (invalid nickname)
User.new(123, 'test', { admin: true, age: 22 })
# => SmartCore::Initializer::ThyTypeValidationError
```

---

## Plugin: dry-types

Support for `Dry::Types` type system ([gem](https://dry-rb.org/gems/dry-types))

- install `dry` types (`gem install dry-types`):

```ruby
gem 'dry-types'
```

```shell
bundle install
```

- enable `dry_types` plugin:

```ruby
require 'dry-types'
SmartCore::Initializer::Configuration.plugin(:dry_types)
```

- usage:

```ruby
class User
include SmartCore::Initializer(type_system: :dry_types)

param :nickname, 'string'
param :email, 'value.text', type_system: :smart_types # mixing with smart_types
option :admin, Dry::Types['bool'], default: false
option :age, Dry::Types['integer']
end

# valid case:
User.new('daiver', '[email protected]', { admin: true, age: 19 })
# => new user object

# invalid case (invalid nickname)
User.new(123, 'test', { admin: true, age: 22 })
# => SmartCore::Initializer::DryTypeValidationError
```

---

## Roadmap

- Attribue Definition DSL
Expand Down
1 change: 1 addition & 0 deletions gemfiles/with_external_deps.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
source 'https://rubygems.org'

gem 'thy', '~> 0.1.4'
gem 'dry-types', '~> 1.4.0'

gemspec path: '..'
29 changes: 29 additions & 0 deletions gemfiles/with_external_deps.gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,42 @@ GEM
rubocop-rake (= 0.5.1)
rubocop-rspec (= 1.42.0)
ast (2.4.1)
coderay (1.1.3)
concurrent-ruby (1.1.6)
diff-lcs (1.3)
docile (1.3.2)
dry-configurable (0.11.6)
concurrent-ruby (~> 1.0)
dry-core (~> 0.4, >= 0.4.7)
dry-equalizer (~> 0.2)
dry-container (0.7.2)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1, >= 0.1.3)
dry-core (0.4.10)
concurrent-ruby (~> 1.0)
dry-equalizer (0.3.0)
dry-inflector (0.2.0)
dry-logic (1.0.8)
concurrent-ruby (~> 1.0)
dry-core (~> 0.2)
dry-equalizer (~> 0.2)
dry-types (1.4.0)
concurrent-ruby (~> 1.0)
dry-container (~> 0.3)
dry-core (~> 0.4, >= 0.4.4)
dry-equalizer (~> 0.3)
dry-inflector (~> 0.1, >= 0.1.2)
dry-logic (~> 1.0, >= 1.0.2)
i18n (1.8.3)
concurrent-ruby (~> 1.0)
method_source (1.0.0)
minitest (5.14.1)
parallel (1.19.2)
parser (2.7.1.4)
ast (~> 2.4.1)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
qonfig (0.24.1)
rack (2.2.3)
rainbow (3.0.0)
Expand Down Expand Up @@ -92,6 +119,8 @@ PLATFORMS
DEPENDENCIES
armitage-rubocop (~> 0.87)
bundler (~> 2.1)
dry-types (~> 1.4.0)
pry
rake (~> 13.0)
rspec (~> 3.9)
simplecov (~> 0.18)
Expand Down
77 changes: 42 additions & 35 deletions gemfiles/without_external_deps.gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,41 +1,46 @@
PATH
remote: ..
specs:
smart_initializer (0.2.0)
smart_initializer (0.3.2)
qonfig (~> 0.24)
smart_engine (~> 0.6)
smart_engine (~> 0.7)
smart_types (~> 0.1.0)

GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.3.1)
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
armitage-rubocop (0.85.0)
rubocop (= 0.85.0)
rubocop-performance (= 1.6.1)
rubocop-rails (= 2.5.2)
armitage-rubocop (0.93.1)
rubocop (= 0.93.1)
rubocop-performance (= 1.8.1)
rubocop-rails (= 2.8.1)
rubocop-rake (= 0.5.1)
rubocop-rspec (= 1.39.0)
ast (2.4.0)
concurrent-ruby (1.1.6)
rubocop-rspec (= 1.43.2)
ast (2.4.1)
coderay (1.1.3)
concurrent-ruby (1.1.7)
diff-lcs (1.3)
docile (1.3.2)
i18n (1.8.3)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
minitest (5.14.1)
parallel (1.19.1)
parser (2.7.1.3)
ast (~> 2.4.0)
qonfig (0.24.1)
rack (2.2.2)
method_source (1.0.0)
minitest (5.14.2)
parallel (1.20.1)
parser (2.7.2.0)
ast (~> 2.4.1)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
qonfig (0.25.0)
rack (2.2.3)
rainbow (3.0.0)
rake (13.0.1)
regexp_parser (1.7.1)
regexp_parser (2.0.0)
rexml (3.2.4)
rspec (3.9.0)
rspec-core (~> 3.9.0)
Expand All @@ -50,47 +55,49 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.3)
rubocop (0.85.0)
rubocop (0.93.1)
parallel (~> 1.10)
parser (>= 2.7.0.1)
parser (>= 2.7.1.5)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
regexp_parser (>= 1.8)
rexml
rubocop-ast (>= 0.0.3)
rubocop-ast (>= 0.6.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.0.3)
parser (>= 2.7.0.1)
rubocop-performance (1.6.1)
rubocop (>= 0.71.0)
rubocop-rails (2.5.2)
activesupport
rubocop-ast (1.2.0)
parser (>= 2.7.1.5)
rubocop-performance (1.8.1)
rubocop (>= 0.87.0)
rubocop-ast (>= 0.4.0)
rubocop-rails (2.8.1)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 0.72.0)
rubocop (>= 0.87.0)
rubocop-rake (0.5.1)
rubocop
rubocop-rspec (1.39.0)
rubocop (>= 0.68.1)
rubocop-rspec (1.43.2)
rubocop (~> 0.87)
ruby-progressbar (1.10.1)
simplecov (0.18.5)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov-html (0.12.2)
smart_engine (0.6.0)
smart_engine (0.8.0)
smart_types (0.1.0)
smart_engine (~> 0.6)
thread_safe (0.3.6)
tzinfo (1.2.7)
tzinfo (1.2.8)
thread_safe (~> 0.1)
unicode-display_width (1.7.0)
zeitwerk (2.3.0)
zeitwerk (2.4.1)

PLATFORMS
ruby

DEPENDENCIES
armitage-rubocop (~> 0.85)
armitage-rubocop (~> 0.87)
bundler (~> 2.1)
pry
rake (~> 13.0)
rspec (~> 3.9)
simplecov (~> 0.18)
Expand Down
4 changes: 2 additions & 2 deletions lib/smart_core/initializer/constructor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def initialize_parameters(instance)
parameter_definitions = Hash[klass.__params__.zip(parameters)]

parameter_definitions.each_pair do |attribute, parameter_value|
if !attribute.type.valid?(parameter_value) && attribute.cast?
if attribute.type.force_cast? || (!attribute.type.valid?(parameter_value) && attribute.cast?)
parameter_value = attribute.type.cast(parameter_value)
end

Expand All @@ -138,7 +138,7 @@ def initialize_options(instance)
klass.__options__.each do |attribute|
option_value = options.fetch(attribute.name) { attribute.default }

if !attribute.type.valid?(option_value) && attribute.cast?
if attribute.type.force_cast? || (!attribute.type.valid?(option_value) && attribute.cast?)
option_value = attribute.type.cast(option_value)
end

Expand Down
2 changes: 2 additions & 0 deletions lib/smart_core/initializer/plugins.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ module SmartCore::Initializer::Plugins
require_relative 'plugins/registry_interface.rb'
require_relative 'plugins/access_mixin'
require_relative 'plugins/thy_types'
require_relative 'plugins/dry_types'

# @since 0.1.0
extend SmartCore::Initializer::Plugins::RegistryInterface

# @since 0.1.0
register_plugin('thy_types', SmartCore::Initializer::Plugins::ThyTypes)
register_plugin('dry_types', SmartCore::Initializer::Plugins::DryTypes)
end
30 changes: 30 additions & 0 deletions lib/smart_core/initializer/plugins/dry_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

# @api private
# @since 0.4.1
class SmartCore::Initializer::Plugins::DryTypes < SmartCore::Initializer::Plugins::Abstract
class << self
# @return [void]
#
# @api private
# @since 0.4.1
def install!
raise(
SmartCore::Initializer::UnresolvedPluginDependencyError,
'::Dry::Types does not exist or "dry-types" gem is not loaded'
) unless const_defined?('::Dry::Types')

# NOTE: require necessary dependencies
require 'date'

# NOTE: add dry-types type system implementation
require_relative 'dry_types/errors'
require_relative 'dry_types/dry_types'

# NOTE: register dry-types type system
SmartCore::Initializer::TypeSystem.register(
:dry_types, SmartCore::Initializer::TypeSystem::DryTypes
)
end
end
end
23 changes: 23 additions & 0 deletions lib/smart_core/initializer/plugins/dry_types/dry_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module SmartCore::Initializer::TypeSystem
# @api public
# @since 0.4.1
class DryTypes < Interop
require_relative 'dry_types/abstract_factory'
require_relative 'dry_types/operation'

type_alias(:any, AbstractFactory.generic_type_object)
type_alias(:nil, ::Dry::Types["nil"])
type_alias(:string, ::Dry::Types["string"])
type_alias(:symbol, ::Dry::Types["symbol"])
type_alias(:integer, ::Dry::Types["integer"])
type_alias(:float, ::Dry::Types["float"])
type_alias(:decimal, ::Dry::Types["decimal"])
type_alias(:boolean, ::Dry::Types["bool"])
type_alias(:time, ::Dry::Types["time"])
type_alias(:date_time, ::Dry::Types["date_time"])
type_alias(:array, ::Dry::Types["array"])
type_alias(:hash, ::Dry::Types["hash"])
end
end
Loading