dry-validation 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -0
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG.md +42 -0
  5. data/Gemfile +8 -1
  6. data/README.md +13 -89
  7. data/config/errors.yml +35 -29
  8. data/dry-validation.gemspec +2 -2
  9. data/examples/basic.rb +3 -7
  10. data/examples/each.rb +3 -8
  11. data/examples/form.rb +3 -6
  12. data/examples/nested.rb +7 -15
  13. data/lib/dry/validation.rb +33 -5
  14. data/lib/dry/validation/error.rb +10 -26
  15. data/lib/dry/validation/error_compiler.rb +69 -99
  16. data/lib/dry/validation/error_compiler/input.rb +148 -0
  17. data/lib/dry/validation/hint_compiler.rb +83 -33
  18. data/lib/dry/validation/input_processor_compiler.rb +98 -0
  19. data/lib/dry/validation/input_processor_compiler/form.rb +46 -0
  20. data/lib/dry/validation/input_processor_compiler/sanitizer.rb +46 -0
  21. data/lib/dry/validation/messages/abstract.rb +30 -10
  22. data/lib/dry/validation/messages/i18n.rb +2 -1
  23. data/lib/dry/validation/messages/namespaced.rb +1 -0
  24. data/lib/dry/validation/messages/yaml.rb +8 -5
  25. data/lib/dry/validation/result.rb +33 -25
  26. data/lib/dry/validation/schema.rb +168 -61
  27. data/lib/dry/validation/schema/attr.rb +5 -27
  28. data/lib/dry/validation/schema/check.rb +24 -0
  29. data/lib/dry/validation/schema/dsl.rb +97 -0
  30. data/lib/dry/validation/schema/form.rb +2 -26
  31. data/lib/dry/validation/schema/key.rb +32 -28
  32. data/lib/dry/validation/schema/rule.rb +88 -32
  33. data/lib/dry/validation/schema/value.rb +77 -27
  34. data/lib/dry/validation/schema_compiler.rb +38 -0
  35. data/lib/dry/validation/version.rb +1 -1
  36. data/spec/fixtures/locales/pl.yml +1 -1
  37. data/spec/integration/attr_spec.rb +122 -0
  38. data/spec/integration/custom_error_messages_spec.rb +9 -11
  39. data/spec/integration/custom_predicates_spec.rb +68 -18
  40. data/spec/integration/error_compiler_spec.rb +259 -65
  41. data/spec/integration/hints_spec.rb +28 -9
  42. data/spec/integration/injecting_rules_spec.rb +11 -12
  43. data/spec/integration/localized_error_messages_spec.rb +16 -16
  44. data/spec/integration/messages/i18n_spec.rb +9 -5
  45. data/spec/integration/optional_keys_spec.rb +9 -11
  46. data/spec/integration/schema/array_schema_spec.rb +23 -0
  47. data/spec/integration/schema/check_rules_spec.rb +39 -31
  48. data/spec/integration/schema/check_with_nth_el_spec.rb +25 -0
  49. data/spec/integration/schema/each_with_set_spec.rb +23 -24
  50. data/spec/integration/schema/form_spec.rb +122 -0
  51. data/spec/integration/schema/inheriting_schema_spec.rb +31 -0
  52. data/spec/integration/schema/input_processor_spec.rb +46 -0
  53. data/spec/integration/schema/macros/confirmation_spec.rb +33 -0
  54. data/spec/integration/schema/macros/maybe_spec.rb +32 -0
  55. data/spec/integration/schema/macros/required_spec.rb +59 -0
  56. data/spec/integration/schema/macros/when_spec.rb +65 -0
  57. data/spec/integration/schema/nested_values_spec.rb +41 -0
  58. data/spec/integration/schema/not_spec.rb +14 -14
  59. data/spec/integration/schema/option_with_default_spec.rb +30 -0
  60. data/spec/integration/schema/reusing_schema_spec.rb +33 -0
  61. data/spec/integration/schema/using_types_spec.rb +29 -0
  62. data/spec/integration/schema/xor_spec.rb +17 -14
  63. data/spec/integration/schema_spec.rb +75 -245
  64. data/spec/shared/rule_compiler.rb +8 -0
  65. data/spec/spec_helper.rb +13 -0
  66. data/spec/unit/hint_compiler_spec.rb +10 -10
  67. data/spec/unit/{input_type_compiler_spec.rb → input_processor_compiler/form_spec.rb} +88 -73
  68. data/spec/unit/schema/key_spec.rb +33 -0
  69. data/spec/unit/schema/rule_spec.rb +7 -6
  70. data/spec/unit/schema/value_spec.rb +187 -54
  71. metadata +53 -31
  72. data/.rubocop.yml +0 -16
  73. data/.rubocop_todo.yml +0 -7
  74. data/lib/dry/validation/input_type_compiler.rb +0 -83
  75. data/lib/dry/validation/schema/definition.rb +0 -74
  76. data/lib/dry/validation/schema/result.rb +0 -68
  77. data/rakelib/rubocop.rake +0 -18
  78. data/spec/integration/rule_groups_spec.rb +0 -94
  79. data/spec/integration/schema/attrs_spec.rb +0 -38
  80. data/spec/integration/schema/default_key_behavior_spec.rb +0 -23
  81. data/spec/integration/schema/grouped_rules_spec.rb +0 -57
  82. data/spec/integration/schema/nested_spec.rb +0 -31
  83. data/spec/integration/schema_form_spec.rb +0 -97
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 341f5b1e89f76e09d7a1d8d2d20cdb68a50a88c1
4
- data.tar.gz: 6dada3ab87730f7fe97e600bb73868c2afba511f
3
+ metadata.gz: 8cb2b0cdd55dfea0aeab8060f8628f55b304c584
4
+ data.tar.gz: ab8689f62590fe6029e427a9563e9da5a1eafe7d
5
5
  SHA512:
6
- metadata.gz: 331d2cd4ea7c0f2b3b96046ad46faf7de8746b1538aaaba8f0fdf07a71546088962653d96cc8b71a3ecba0b04850367b19841f0418d083702666e154890bf29c
7
- data.tar.gz: ec3ec948092ab30ad982498ca234b385c66e136ec351cc0b8754f041a46a23cc59049b34fae76aec31d2cc46a2f11d91b9f469c862cc991c4605531600d31d39
6
+ metadata.gz: 35a95e790addbea7fbabd6d60c0ac130db75f30248c0ff7f51583bb893d7422c8fd2b60e6dcb462d5fb7a242e0980dede8cdc6df1076667e60110e69babcc081
7
+ data.tar.gz: 55cd8947019a5326256afca381c58538c6c272874ecf34ae942809dc5af3ba5d1cb294864701b0ce415b23d2a82ae7765242e8c1bcd79b8b1c20233d0ba670a7
@@ -7,6 +7,7 @@ engines:
7
7
  Rubocop/Style/StabbyLambdaParentheses:
8
8
  enabled: false
9
9
  Rubocop/Metrics/CyclomaticComplexity:
10
+ enabled: true
10
11
  Max: 10
11
12
  ratings:
12
13
  paths:
@@ -1,13 +1,14 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  cache: bundler
4
- bundler_args: --without console
4
+ bundler_args: --without console benchmarks
5
5
  script:
6
6
  - bundle exec rake spec
7
7
  rvm:
8
8
  - 2.0
9
9
  - 2.1
10
10
  - 2.2
11
+ - 2.3.0
11
12
  - rbx-2
12
13
  - jruby-9000
13
14
  - ruby-head
@@ -17,9 +18,9 @@ env:
17
18
  - JRUBY_OPTS='--dev -J-Xmx1024M'
18
19
  matrix:
19
20
  allow_failures:
21
+ - rvm: rbx-2
20
22
  - rvm: ruby-head
21
23
  - rvm: jruby-head
22
- - rvm: jruby-9000
23
24
  notifications:
24
25
  email: false
25
26
  webhooks:
@@ -1,3 +1,45 @@
1
+ # v0.7.0 2016-03-16
2
+
3
+ ### Added
4
+
5
+ * Support for macros:
6
+ * `required` - when value must be filled
7
+ * `maybe` - when value can be nil (or empty, in case of `Form`)
8
+ * `when` - for composing high-level rule based on predicates applied to a
9
+ validated value
10
+ * `confirmation` - for confirmation validation
11
+ * Support for `value(:foo).eql?(value(:bar))` syntax in high-level rules (solnic)
12
+ * New DSL for defining schema objects `Dry::Validation.Schema do .. end` (solnic)
13
+ * Ability to define a schema for an array via top-level `each` rule (solnic)
14
+ * Ability to define nested schemas via `key(:location).schema do .. end` (solnic)
15
+ * Ability to re-use schemas inside other schemas via `key(:location).schema(LocationSchema)` (solnic)
16
+ * Ability to inherit rules from another schema via `Dry::Validation.Schema(Other) do .. end` (solnic)
17
+ * Ability to inject arbitrary dependencies to schemas via `Schema.option` + `Schema#with` (solnic)
18
+ * Ability to provide translations for rule names under `%{locale}.rules.%{name}` pattern (solnic)
19
+ * Ability to configure input processor, either `:form` or `:sanitizer` (solnic)
20
+ * Ability to pass a constrained dry type when defining keys or attrs, ie `key(:age, Types::Age)` (solnic)
21
+ * `Result#messages` supports `:full` option to get messages with rule names, disabled by default (solnic)
22
+ * `Validation::Result` responds to `#[]` and `#each` (delegating to its output)
23
+ and it's an enumerable (solnic)
24
+
25
+ ### Changed
26
+
27
+ * `schema` was **removed** from the DSL, just use `key(:name).schema` instead (solnic)
28
+ * `confirmation` is now a macro that you can call on a key rule (solnic)
29
+ * rule names for nested structures are now fully qualified, which means you can
30
+ provide customized messages for them. ie `user: :email` (solnic)
31
+ * `Schema::Result#params` was renamed to `#output` (solnic)
32
+ * `Schema::Result` is now `Validation::Result` and it no longer has success and
33
+ failure results, only error results are provided (solnic)
34
+
35
+ ### Fixed
36
+
37
+ * Qualified rule names properly use last node by default for error messages (solnic)
38
+ * Validation hints only include relevant messages (solnic)
39
+ * `:yaml` messages respect `:locale` option in `Result#messages` (solnic)
40
+
41
+ [Compare v0.6.0...v0.7.0](https://github.com/dryrb/dry-validation/compare/v0.6.0...v0.7.0)
42
+
1
43
  # v0.6.0 2016-01-20
2
44
 
3
45
  ### Added
data/Gemfile CHANGED
@@ -8,9 +8,16 @@ group :test do
8
8
  end
9
9
 
10
10
  group :tools do
11
- gem 'rubocop'
12
11
  gem 'guard'
13
12
  gem 'guard-rspec'
14
13
  gem 'guard-rubocop'
15
14
  gem 'byebug', platform: :mri
16
15
  end
16
+
17
+ group :benchmarks do
18
+ gem 'hotch'
19
+ gem 'activemodel', '5.0.0.beta3'
20
+ gem 'actionpack', '5.0.0.beta3'
21
+ gem 'benchmark-ips'
22
+ gem 'virtus'
23
+ end
data/README.md CHANGED
@@ -1,98 +1,22 @@
1
1
  [gem]: https://rubygems.org/gems/dry-validation
2
- [travis]: https://travis-ci.org/dryrb/dry-validation
3
- [gemnasium]: https://gemnasium.com/dryrb/dry-validation
4
- [codeclimate]: https://codeclimate.com/github/dryrb/dry-validation
5
- [coveralls]: https://coveralls.io/r/dryrb/dry-validation
6
- [inchpages]: http://inch-ci.org/github/dryrb/dry-validation
2
+ [travis]: https://travis-ci.org/dry-rb/dry-validation
3
+ [gemnasium]: https://gemnasium.com/dry-rb/dry-validation
4
+ [codeclimate]: https://codeclimate.com/github/dry-rb/dry-validation
5
+ [coveralls]: https://coveralls.io/r/dry-rb/dry-validation
6
+ [inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
7
7
 
8
- # dry-validation [![Join the chat at https://gitter.im/dryrb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dryrb/chat)
8
+ # dry-validation [![Join the chat at https://gitter.im/dry-rb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dry-rb/chat)
9
9
 
10
10
  [![Gem Version](https://badge.fury.io/rb/dry-validation.svg)][gem]
11
- [![Build Status](https://travis-ci.org/dryrb/dry-validation.svg?branch=master)][travis]
12
- [![Dependency Status](https://gemnasium.com/dryrb/dry-validation.svg)][gemnasium]
13
- [![Code Climate](https://codeclimate.com/github/dryrb/dry-validation/badges/gpa.svg)][codeclimate]
14
- [![Test Coverage](https://codeclimate.com/github/dryrb/dry-validation/badges/coverage.svg)][codeclimate]
15
- [![Inline docs](http://inch-ci.org/github/dryrb/dry-validation.svg?branch=master)][inchpages]
11
+ [![Build Status](https://travis-ci.org/dry-rb/dry-validation.svg?branch=master)][travis]
12
+ [![Dependency Status](https://gemnasium.com/dry-rb/dry-validation.svg)][gemnasium]
13
+ [![Code Climate](https://codeclimate.com/github/dry-rb/dry-validation/badges/gpa.svg)][codeclimate]
14
+ [![Test Coverage](https://codeclimate.com/github/dry-rb/dry-validation/badges/coverage.svg)][codeclimate]
15
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=master)][inchpages]
16
16
 
17
- Data validation library based on predicate logic and rule composition.
17
+ ## Links
18
18
 
19
- ## Overview
20
-
21
- Unlike other, well known, validation solutions in Ruby, `dry-validation` takes
22
- a different approach and focuses a lot on explicitness, clarity and preciseness
23
- of validation logic. It is designed to work with any data input, whether it's a
24
- simple hash, an array or a complex object with deeply nested data.
25
-
26
- It is based on an idea that each validation is encapsulated by a simple,
27
- stateless predicate, that receives some input and returns either `true` or `false`.
28
-
29
- Those predicates are encapsulated by `rules` which can be composed together using
30
- `predicate logic`. This means you can use the common logic operators to build up
31
- a validation `schema`.
32
-
33
- Validations can be described with great precision, `dry-validation` eliminates
34
- ambigious concepts like `presence` validation where we can't really say whether
35
- some attribute or key is *missing* or it's just that the value is `nil`.
36
-
37
- In `dry-validation` type-safety is a first-class feature, something that's completely
38
- missing in other validation libraries, and it's an important and useful feature. It
39
- means you can compose a validation that does rely on the type of a given value. In
40
- example it makes no sense to validate each element of an array when it turns out to
41
- be an empty string.
42
-
43
- ## The DSL
44
-
45
- The core of `dry-validation` is rule composition and predicate logic provided by
46
- [dry-logic](https://github.com/dryrb/dry-logic). The DSL is a simple front-end
47
- for it. It only allows you to define the rules by using predicate identifiers.
48
- There are no magical options, conditionals and custom validation blocks known from
49
- other libraries. The focus is on pure validation logic expressed in a concise way.
50
-
51
- The DSL is very abstract, it builds [a rule AST](https://github.com/dryrb/dry-validation/wiki/Rule-AST)
52
- which is compiled into an array of rule objects. This means alternative interfaces could
53
- be easily build.
54
-
55
- ## When To Use?
56
-
57
- Always and everywhere. This is a general-purpose validation library that can be used for many things and **it's multiple times faster** than `ActiveRecord`/`ActiveModel::Validations` *and* `strong-parameters`.
58
-
59
- Possible use-cases include validation of:
60
-
61
- * Form params
62
- * "GET" params
63
- * JSON documents
64
- * YAML documents
65
- * Application configuration (ie stored in ENV)
66
- * Replacement for `ActiveRecord`/`ActiveModel::Validations`
67
- * Replacement for `strong-parameters`
68
- * etc.
69
-
70
- ## Synopsis
71
-
72
- Please refer to [the wiki](https://github.com/dryrb/dry-validation/wiki) for full usage documentation.
73
-
74
- ``` ruby
75
- class UserSchema < Dry::Validation::Schema
76
- key(:name) { |name| name.filled? }
77
-
78
- key(:email) { |email| email.filled? & email.format?(EMAIL_REGEX) }
79
-
80
- key(:age) { |age| age.none? | age.int? }
81
-
82
- key(:address) do |address|
83
- address.key(:street, &:filled?)
84
- address.key(:city, &:filled?)
85
- address.key(:zipcode, &:filled?)
86
- end
87
- end
88
- ```
89
-
90
- ## Status and Roadmap
91
-
92
- This library is in an early stage of development but you are encouraged to
93
- try it out and provide feedback.
94
-
95
- For planned features check out [the issues](https://github.com/dryrb/dry-validation/labels/feature).
19
+ * [Documentation](http://dry-rb.org/gems/dry-validation)
96
20
 
97
21
  ## License
98
22
 
@@ -1,62 +1,68 @@
1
1
  en:
2
2
  errors:
3
- array?: "%{name} must be an array"
3
+ array?: "must be an array"
4
4
 
5
- empty?: "%{name} cannot be empty"
5
+ empty?: "cannot be empty"
6
6
 
7
- exclusion?: "%{name} must not be one of: %{list}"
7
+ exclusion?: "must not be one of: %{list}"
8
8
 
9
- eql?: "%{name} must be equal to %{eql_value}"
9
+ eql?: "must be equal to %{eql_value}"
10
10
 
11
- filled?: "%{name} must be filled"
11
+ filled?: "must be filled"
12
12
 
13
- format?: "%{name} is in invalid format"
13
+ format?: "is in invalid format"
14
14
 
15
- gt?: "%{name} must be greater than %{num}"
15
+ gt?: "must be greater than %{num}"
16
16
 
17
- gteq?: "%{name} must be greater than or equal to %{num}"
17
+ gteq?: "must be greater than or equal to %{num}"
18
18
 
19
- hash?: "%{name} must be a hash"
19
+ hash?: "must be a hash"
20
20
 
21
- inclusion?: "%{name} must be one of: %{list}"
21
+ inclusion?: "must be one of: %{list}"
22
22
 
23
- bool?: "%{name} must be boolean"
23
+ bool?: "must be boolean"
24
24
 
25
- int?: "%{name} must be an integer"
25
+ true?: "must be true"
26
26
 
27
- float?: "%{name} must be a float"
27
+ false?: "must be false"
28
28
 
29
- decimal?: "%{name} must be a decimal"
29
+ int?: "must be an integer"
30
30
 
31
- date?: "%{name} must be a date"
31
+ float?: "must be a float"
32
32
 
33
- date_time?: "%{name} must be a date time"
33
+ decimal?: "must be a decimal"
34
34
 
35
- time?: "%{name} must be a time"
35
+ date?: "must be a date"
36
36
 
37
- key?: "%{name} is missing"
37
+ date_time?: "must be a date time"
38
38
 
39
- attr?: "%{name} is missing"
39
+ time?: "must be a time"
40
40
 
41
- lt?: "%{name} must be less than %{num} (%{value} was given)"
41
+ key?: "is missing"
42
42
 
43
- lteq?: "%{name} must be less than or equal to %{num}"
43
+ attr?: "is missing"
44
44
 
45
- max_size?: "%{name} size cannot be greater than %{num}"
45
+ lt?: "must be less than %{num} (%{value} was given)"
46
46
 
47
- min_size?: "%{name} size cannot be less than %{num}"
47
+ lteq?: "must be less than or equal to %{num}"
48
48
 
49
- none?: "%{name} cannot be defined"
49
+ max_size?: "size cannot be greater than %{num}"
50
50
 
51
- str?: "%{name} must be a string"
51
+ min_size?: "size cannot be less than %{num}"
52
+
53
+ none?: "cannot be defined"
54
+
55
+ str?: "must be a string"
56
+
57
+ type?: "must be %{type}"
52
58
 
53
59
  size?:
54
60
  arg:
55
- default: "%{name} size must be %{num}"
56
- range: "%{name} size must be within %{left} - %{right}"
61
+ default: "size must be %{num}"
62
+ range: "size must be within %{left} - %{right}"
57
63
 
58
64
  value:
59
65
  string:
60
66
  arg:
61
- default: "%{name} length must be %{num}"
62
- range: "%{name} length must be within %{left} - %{right}"
67
+ default: "length must be %{num}"
68
+ range: "length must be within %{left} - %{right}"
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.add_runtime_dependency 'dry-configurable', '~> 0.1', '>= 0.1.3'
19
19
  spec.add_runtime_dependency 'dry-container', '~> 0.2', '>= 0.2.8'
20
20
  spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
21
- spec.add_runtime_dependency 'dry-logic', '~> 0.1', '>= 0.1.2'
22
- spec.add_runtime_dependency 'dry-data', '~> 0.5', '>= 0.5.0'
21
+ spec.add_runtime_dependency 'dry-logic', '~> 0.2', '>= 0.2.0'
22
+ spec.add_runtime_dependency 'dry-types', '~> 0.6', '>= 0.6.0'
23
23
 
24
24
  spec.add_development_dependency 'bundler'
25
25
  spec.add_development_dependency 'rake'
@@ -1,15 +1,11 @@
1
1
  require 'dry-validation'
2
2
 
3
- class Schema < Dry::Validation::Schema
4
- key(:email) { |email| email.filled? }
3
+ schema = Dry::Validation.Schema do
4
+ key(:email).required
5
5
 
6
- key(:age) do |age|
7
- age.int? & age.gt?(18)
8
- end
6
+ key(:age).required(:int?, gt?: 18)
9
7
  end
10
8
 
11
- schema = Schema.new
12
-
13
9
  errors = schema.call(email: 'jane@doe.org', age: 19).messages
14
10
 
15
11
  puts errors.inspect
@@ -1,15 +1,10 @@
1
+ require 'byebug'
1
2
  require 'dry-validation'
2
3
 
3
- class Schema < Dry::Validation::Schema
4
- key(:phone_numbers) do |phone_numbers|
5
- phone_numbers.array? do
6
- phone_numbers.each(&:str?)
7
- end
8
- end
4
+ schema = Dry::Validation.Schema do
5
+ key(:phone_numbers).each(:str?)
9
6
  end
10
7
 
11
- schema = Schema.new
12
-
13
8
  errors = schema.call(phone_numbers: '').messages
14
9
 
15
10
  puts errors.inspect
@@ -1,14 +1,11 @@
1
1
  require 'dry-validation'
2
- require 'dry/validation/schema/form'
3
2
 
4
- class UserFormSchema < Dry::Validation::Schema::Form
5
- key(:email) { |value| value.str? & value.filled? }
3
+ schema = Dry::Validation.Form do
4
+ key(:email).required
6
5
 
7
- key(:age) { |value| value.int? & value.gt?(18) }
6
+ key(:age).required(:int?, gt?: 18)
8
7
  end
9
8
 
10
- schema = UserFormSchema.new
11
-
12
9
  errors = schema.call('email' => '', 'age' => '18').messages
13
10
 
14
11
  puts errors.inspect
@@ -1,26 +1,18 @@
1
1
  require 'dry-validation'
2
2
 
3
- class Schema < Dry::Validation::Schema
4
- key(:address) do |address|
5
- address.hash? do
6
- address.key(:city) do |city|
7
- city.min_size?(3)
8
- end
3
+ schema = Dry::Validation.Schema do
4
+ key(:address).schema do
5
+ key(:city).required(min_size?: 3)
9
6
 
10
- address.key(:street) do |street|
11
- street.filled?
12
- end
7
+ key(:street).required
13
8
 
14
- address.key(:country) do |country|
15
- country.key(:name, &:filled?)
16
- country.key(:code, &:filled?)
17
- end
9
+ key(:country).schema do
10
+ key(:name).required
11
+ key(:code).required
18
12
  end
19
13
  end
20
14
  end
21
15
 
22
- schema = Schema.new
23
-
24
16
  errors = schema.call({}).messages
25
17
 
26
18
  puts errors.inspect
@@ -2,15 +2,43 @@ require 'dry-equalizer'
2
2
  require 'dry-configurable'
3
3
  require 'dry-container'
4
4
 
5
- # A collection of micro-libraries, each intended to encapsulate
6
- # a common task in Ruby
5
+ require 'dry/validation/schema'
6
+ require 'dry/validation/schema/form'
7
+
7
8
  module Dry
8
9
  module Validation
10
+ MissingMessageError = Class.new(StandardError)
11
+
9
12
  def self.messages_paths
10
13
  Messages::Abstract.config.paths
11
14
  end
15
+
16
+ def self.Schema(base = Schema, **options, &block)
17
+ dsl_opts = {
18
+ schema_class: Class.new(base.is_a?(Schema) ? base.class : base),
19
+ parent: options[:parent]
20
+ }
21
+
22
+ dsl = Schema::Value.new(dsl_opts)
23
+ dsl.instance_exec(&block)
24
+
25
+ klass = dsl.schema_class
26
+
27
+ klass.configure do |config|
28
+ config.rules = config.rules + (options.fetch(:rules, []) + dsl.rules)
29
+ config.checks = config.checks + dsl.checks
30
+ config.path = dsl.path
31
+ end
32
+
33
+ if options[:build] == false
34
+ klass
35
+ else
36
+ klass.new
37
+ end
38
+ end
39
+
40
+ def self.Form(options = {}, &block)
41
+ Validation.Schema(Schema::Form, options, &block)
42
+ end
12
43
  end
13
44
  end
14
-
15
- require 'dry/validation/schema'
16
- require 'dry/validation/schema/form'