dry-validation 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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'