dry-validation 0.1.0 → 1.8.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 (82) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +969 -1
  3. data/LICENSE +1 -1
  4. data/README.md +19 -286
  5. data/config/errors.yml +4 -35
  6. data/dry-validation.gemspec +38 -22
  7. data/lib/dry/validation/config.rb +24 -0
  8. data/lib/dry/validation/constants.rb +43 -0
  9. data/lib/dry/validation/contract/class_interface.rb +230 -0
  10. data/lib/dry/validation/contract.rb +173 -0
  11. data/lib/dry/validation/evaluator.rb +233 -0
  12. data/lib/dry/validation/extensions/hints.rb +67 -0
  13. data/lib/dry/validation/extensions/monads.rb +34 -0
  14. data/lib/dry/validation/extensions/predicates_as_macros.rb +75 -0
  15. data/lib/dry/validation/failures.rb +70 -0
  16. data/lib/dry/validation/function.rb +43 -0
  17. data/lib/dry/validation/macro.rb +38 -0
  18. data/lib/dry/validation/macros.rb +104 -0
  19. data/lib/dry/validation/message.rb +100 -0
  20. data/lib/dry/validation/message_set.rb +97 -0
  21. data/lib/dry/validation/messages/resolver.rb +129 -0
  22. data/lib/dry/validation/result.rb +206 -38
  23. data/lib/dry/validation/rule.rb +116 -106
  24. data/lib/dry/validation/schema_ext.rb +19 -0
  25. data/lib/dry/validation/values.rb +108 -0
  26. data/lib/dry/validation/version.rb +3 -1
  27. data/lib/dry/validation.rb +55 -7
  28. data/lib/dry-validation.rb +3 -1
  29. metadata +80 -106
  30. data/.gitignore +0 -8
  31. data/.rspec +0 -3
  32. data/.rubocop.yml +0 -16
  33. data/.rubocop_todo.yml +0 -7
  34. data/.travis.yml +0 -29
  35. data/Gemfile +0 -11
  36. data/Rakefile +0 -12
  37. data/examples/basic.rb +0 -21
  38. data/examples/nested.rb +0 -30
  39. data/examples/rule_ast.rb +0 -33
  40. data/lib/dry/validation/error.rb +0 -43
  41. data/lib/dry/validation/error_compiler.rb +0 -116
  42. data/lib/dry/validation/messages.rb +0 -71
  43. data/lib/dry/validation/predicate.rb +0 -39
  44. data/lib/dry/validation/predicate_set.rb +0 -22
  45. data/lib/dry/validation/predicates.rb +0 -88
  46. data/lib/dry/validation/rule_compiler.rb +0 -57
  47. data/lib/dry/validation/schema/definition.rb +0 -15
  48. data/lib/dry/validation/schema/key.rb +0 -39
  49. data/lib/dry/validation/schema/rule.rb +0 -28
  50. data/lib/dry/validation/schema/value.rb +0 -31
  51. data/lib/dry/validation/schema.rb +0 -74
  52. data/rakelib/rubocop.rake +0 -18
  53. data/spec/fixtures/errors.yml +0 -4
  54. data/spec/integration/custom_error_messages_spec.rb +0 -35
  55. data/spec/integration/custom_predicates_spec.rb +0 -57
  56. data/spec/integration/validation_spec.rb +0 -118
  57. data/spec/shared/predicates.rb +0 -31
  58. data/spec/spec_helper.rb +0 -18
  59. data/spec/unit/error_compiler_spec.rb +0 -165
  60. data/spec/unit/predicate_spec.rb +0 -37
  61. data/spec/unit/predicates/empty_spec.rb +0 -38
  62. data/spec/unit/predicates/eql_spec.rb +0 -21
  63. data/spec/unit/predicates/exclusion_spec.rb +0 -35
  64. data/spec/unit/predicates/filled_spec.rb +0 -38
  65. data/spec/unit/predicates/format_spec.rb +0 -21
  66. data/spec/unit/predicates/gt_spec.rb +0 -40
  67. data/spec/unit/predicates/gteq_spec.rb +0 -40
  68. data/spec/unit/predicates/inclusion_spec.rb +0 -35
  69. data/spec/unit/predicates/int_spec.rb +0 -34
  70. data/spec/unit/predicates/key_spec.rb +0 -29
  71. data/spec/unit/predicates/lt_spec.rb +0 -40
  72. data/spec/unit/predicates/lteq_spec.rb +0 -40
  73. data/spec/unit/predicates/max_size_spec.rb +0 -49
  74. data/spec/unit/predicates/min_size_spec.rb +0 -49
  75. data/spec/unit/predicates/nil_spec.rb +0 -28
  76. data/spec/unit/predicates/size_spec.rb +0 -49
  77. data/spec/unit/predicates/str_spec.rb +0 -32
  78. data/spec/unit/rule/each_spec.rb +0 -20
  79. data/spec/unit/rule/key_spec.rb +0 -27
  80. data/spec/unit/rule/set_spec.rb +0 -32
  81. data/spec/unit/rule/value_spec.rb +0 -42
  82. data/spec/unit/rule_compiler_spec.rb +0 -86
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Ruby Object Mapper
3
+ Copyright (c) 2015-2021 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,296 +1,29 @@
1
- # dry-validation <a href="https://gitter.im/dryrb/chat" target="_blank">![Join the chat at https://gitter.im/dryrb/chat](https://badges.gitter.im/Join%20Chat.svg)</a>
1
+ <!--- this file is synced from dry-rb/template-gem project -->
2
+ [gem]: https://rubygems.org/gems/dry-validation
3
+ [actions]: https://github.com/dry-rb/dry-validation/actions
4
+ [codacy]: https://www.codacy.com/gh/dry-rb/dry-validation
5
+ [chat]: https://dry-rb.zulipchat.com
6
+ [inchpages]: http://inch-ci.org/github/dry-rb/dry-validation
2
7
 
3
- <a href="https://rubygems.org/gems/dry-validation" target="_blank">![Gem Version](https://badge.fury.io/rb/dry-validation.svg)</a>
4
- <a href="https://travis-ci.org/dryrb/dry-validation" target="_blank">![Build Status](https://travis-ci.org/dryrb/dry-validation.svg?branch=master)</a>
5
- <a href="https://gemnasium.com/dryrb/dry-validation" target="_blank">![Dependency Status](https://gemnasium.com/dryrb/dry-validation.svg)</a>
6
- <a href="https://codeclimate.com/github/dryrb/dry-validation" target="_blank">![Code Climate](https://codeclimate.com/github/dryrb/dry-validation/badges/gpa.svg)</a>
7
- <a href="http://inch-ci.org/github/dryrb/dry-validation" target="_blank">![Documentation Status](http://inch-ci.org/github/dryrb/dry-validation.svg?branch=master&style=flat)</a>
8
+ # dry-validation [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
9
 
9
- Data validation library based on predicate logic and rule composition.
10
+ [![Gem Version](https://badge.fury.io/rb/dry-validation.svg)][gem]
11
+ [![CI Status](https://github.com/dry-rb/dry-validation/workflows/ci/badge.svg)][actions]
12
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
13
+ [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/f30e3ff5ec304c55a73868cdbf055c67)][codacy]
14
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-validation.svg?branch=master)][inchpages]
10
15
 
11
- ## Overview
16
+ ## Links
12
17
 
13
- Unlike other, well known, validation solutions in Ruby, `dry-validation` takes
14
- a different approach and focuses a lot on explicitness, clarity and preciseness
15
- of validation logic. It is designed to work with any data input, whether it's a
16
- simple hash, an array or a complex object with deeply nested data.
18
+ * [User documentation](https://dry-rb.org/gems/dry-validation)
19
+ * [API documentation](http://rubydoc.info/gems/dry-validation)
17
20
 
18
- It is based on a simple idea that each validation is encapsulated by a simple,
19
- stateless predicate, that receives some input and returns either `true` or `false`.
21
+ ## Supported Ruby versions
20
22
 
21
- Those predicates are encapsulated by `rules` which can be composed together using
22
- `predicate logic`. This means you can use the common logic operators to build up
23
- a validation `schema`.
23
+ This library officially supports the following Ruby versions:
24
24
 
25
- It's very explicit, powerful and extendible.
26
-
27
- Validations can be described with great precision, `dry-validation` eliminates
28
- ambigious concepts like `presence` validation where we can't really say whether
29
- some attribute or key is *missing* or it's just that the value is `nil`.
30
-
31
- There's also the concept of type-safety, completely missing in other validation
32
- libraries, which is quite important and useful. It means you can compose a validation
33
- that does rely on the type of a given value. In example it makes no sense to validate
34
- each element of an array when it turns out to be an empty string.
35
-
36
- ## The DSL
37
-
38
- The core of `dry-validation` is rules composition and predicate logic. The DSL
39
- is a simple front-end for that. It only allows you to define the rules by using
40
- predicate identifiers. There are no magical options, conditionals and custom
41
- validation blocks known from other libraries. The focus is on pure validation
42
- logic.
43
-
44
- ## Examples
45
-
46
- ### Basic
47
-
48
- Here's a basic example where we validate following things:
49
-
50
- * The input *must have a key* called `:email`
51
- * Provided the email key is present, its value *must be filled*
52
- * The input *must have a key* called `:age`
53
- * Provided the age key is present, its value *must be an integer* and it *must be greater than 18*
54
-
55
- This can be easily expressed through the DSL:
56
-
57
- ``` ruby
58
- require 'dry-validation'
59
-
60
- class Schema < Dry::Validation::Schema
61
- key(:email) { |email| email.filled? }
62
-
63
- key(:age) do |age|
64
- age.int? & age.gt?(18)
65
- end
66
- end
67
-
68
- schema = Schema.new
69
-
70
- errors = schema.messages(email: 'jane@doe.org', age: 19)
71
-
72
- puts errors.inspect
73
- # []
74
-
75
- errors = schema.messages(email: nil, age: 19)
76
-
77
- puts errors.inspect
78
- # [[:email, ["email must be filled"]]]
79
- ```
80
-
81
- A couple of remarks:
82
-
83
- * `key` assumes that we want to use the `:key?` predicate to check the existance of that key
84
- * `age.gt?(18)` translates to calling a predicate like this: `schema[:gt?].(18, age)`
85
- * `age.int? & age.gt?(18)` is a conjunction, so we don't bother about `gt?` unless `int?` returns `true`
86
- * You can also use `|` for disjunction
87
- * Schema object does not carry the input as its state, nor does it know how to access the input values, we
88
- pass the input to `call` and get error set as the response
89
-
90
- ### Nested Hash
91
-
92
- We are free to define validations for anything, including deeply nested structures:
93
-
94
- ``` ruby
95
- require 'dry-validation'
96
-
97
- class Schema < Dry::Validation::Schema
98
- key(:address) do |address|
99
- address.key(:city) do |city|
100
- city.min_size?(3)
101
- end
102
-
103
- address.key(:street) do |street|
104
- street.filled?
105
- end
106
-
107
- address.key(:country) do |country|
108
- country.key(:name, &:filled?)
109
- country.key(:code, &:filled?)
110
- end
111
- end
112
- end
113
-
114
- schema = Schema.new
115
-
116
- errors = schema.messages({})
117
-
118
- puts errors.inspect
119
- # [[:address, ["address is missing"]]]
120
-
121
- errors = schema.messages(address: { city: 'NYC' })
122
-
123
- puts errors.inspect
124
- # [[:address, [[:street, ["street is missing"]], [:country, ["country is missing"]]]]]
125
- ```
126
-
127
- ### Defining Custom Predicates
128
-
129
- You can simply define predicate methods on your schema object:
130
-
131
- ``` ruby
132
- class Schema < Dry::Validation::Schema
133
- key(:email) { |value| value.str? & value.email? }
134
-
135
- def email?(value)
136
- ! /magical-regex-that-matches-emails/.match(value).nil?
137
- end
138
- end
139
- ```
140
-
141
- You can also re-use a predicate container across multiple schemas:
142
-
143
- ``` ruby
144
- module MyPredicates
145
- include Dry::Validation::Predicates
146
-
147
- predicate(:email?) do |input|
148
- ! /magical-regex-that-matches-emails/.match(value).nil?
149
- end
150
- end
151
-
152
- class Schema < Dry::Validation::Schema
153
- configure do |config|
154
- config.predicates = MyPredicates
155
- end
156
-
157
- key(:email) { |value| value.str? & value.email? }
158
- end
159
- ```
160
-
161
- ## List of Built-In Predicates
162
-
163
- * `empty?`
164
- * `eql?`
165
- * `exclusion?`
166
- * `filled?`
167
- * `format?`
168
- * `gt?`
169
- * `gteq?`
170
- * `inclusion?`
171
- * `int?`
172
- * `key?`
173
- * `lt?`
174
- * `lteq?`
175
- * `max_size?`
176
- * `min_size?`
177
- * `nil?`
178
- * `size?`
179
- * `str?`
180
-
181
- ## Error Messages
182
-
183
- By default `dry-validation` comes with a set of pre-defined error messages for
184
- every built-in predicate. They are defined in [a yaml file](https://github.com/dryrb/dry-validation/blob/master/config/errors.yml)
185
- which is shipped with the gem.
186
-
187
- You can provide your own messages and configure your schemas to use it like that:
188
-
189
- ``` ruby
190
- class Schema < Dry::Validation::Schema
191
- configure { |config| config.messages_file = '/path/to/my/errors.yml' }
192
- end
193
- ```
194
-
195
- You can also provide a namespace per-schema that will be used by default:
196
-
197
- ``` ruby
198
- class Schema < Dry::Validation::Schema
199
- configure { |config| config.namespace = :user }
200
- end
201
- ```
202
-
203
- Lookup rules:
204
-
205
- ``` yaml
206
- filled?: "%{name} must be filled"
207
-
208
- attributes:
209
- email:
210
- filled?: "the email is missing"
211
-
212
- user:
213
- filled?: "%{name} name cannot be blank"
214
-
215
- attributes:
216
- address:
217
- filled?: "You gotta tell us where you live"
218
- ```
219
-
220
- Given the yaml file above, messages lookup works as follows:
221
-
222
- ``` ruby
223
- messages = Dry::Validation::Messages.load('/path/to/our/errors.yml')
224
-
225
- messages.lookup(:filled?, :age) # => "age must be filled"
226
- messages.lookup(:filled?, :address) # => "address must be filled"
227
- messages.lookup(:filled?, :email) # => "the email is missing"
228
-
229
- # with namespaced messages
230
- user_messages = messages.namespaced(:user)
231
-
232
- user_messages.lookup(:filled?, :age) # "age cannot be blank"
233
- user_messages.lookup(:filled?, :address) # "You gotta tell us where you live"
234
- ```
235
-
236
- By configuring `messages_file` and/or `namespace` in a schema, default messages
237
- are going to be automatically merged with your overrides and/or namespaced.
238
-
239
- ## I18n Integration
240
-
241
- Coming (very) soon...
242
-
243
- ## Rule AST
244
-
245
- Internally, `dry-validation` uses a simple AST representation of rules and errors
246
- to produce rule objects and error messages. If you would like to programatically
247
- generate rules, it is a very simple process:
248
-
249
- ``` ruby
250
- ast = [
251
- [
252
- :and,
253
- [
254
- [:key, [:age, [:predicate, [:key?, []]]]],
255
- [
256
- :and,
257
- [
258
- [:val, [:age, [:predicate, [:filled?, []]]]],
259
- [:val, [:age, [:predicate, [:gt?, [18]]]]]
260
- ]
261
- ]
262
- ]
263
- ]
264
- ]
265
-
266
- compiler = Dry::Validation::RuleCompiler.new(Dry::Validation::Predicates)
267
-
268
- # compile an array of rule objects
269
- rules = compiler.call(ast)
270
-
271
- puts rules.inspect
272
- # [
273
- # #<Dry::Validation::Rule::Conjunction
274
- # left=#<Dry::Validation::Rule::Key name=:age predicate=#<Dry::Validation::Predicate id=:key?>>
275
- # right=#<Dry::Validation::Rule::Conjunction
276
- # left=#<Dry::Validation::Rule::Value name=:age predicate=#<Dry::Validation::Predicate id=:filled?>>
277
- # right=#<Dry::Validation::Rule::Value name=:age predicate=#<Dry::Validation::Predicate id=:gt?>>>>
278
- # ]
279
-
280
- # dump it back to ast
281
- puts rules.map(&:to_ary).inspect
282
- # [[:and, [:key, [:age, [:predicate, [:key?, [:age]]]]], [[:and, [:val, [:age, [:predicate, [:filled?, []]]]], [[:val, [:age, [:predicate, [:gt?, [18]]]]]]]]]]
283
- ```
284
-
285
- Complete docs for the AST format are coming soon, for now please refer to
286
- [this spec](https://github.com/dryrb/dry-validation/blob/master/spec/unit/rule_compiler_spec.rb).
287
-
288
- ## Status and Roadmap
289
-
290
- This library is in a very early stage of development but you are encauraged to
291
- try it out and provide feedback.
292
-
293
- For planned features check out [the issues](https://github.com/dryrb/dry-validation/labels/feature).
25
+ * MRI `>= 2.7.0`
26
+ * jruby `>= 9.3` (postponed until 2.7 is supported)
294
27
 
295
28
  ## License
296
29
 
data/config/errors.yml CHANGED
@@ -1,35 +1,4 @@
1
- empty?: "%{name} cannot be empty"
2
-
3
- exclusion?: "%{name} must not be one of: %{list}"
4
-
5
- eql?: "%{name} must be equal to %{eql_value}"
6
-
7
- filled?: "%{name} must be filled"
8
-
9
- format?: "%{name} is in invalid format"
10
-
11
- gt?: "%{name} must be greater than %{num} (%{value} was given)"
12
-
13
- gteq?: "%{name} must be greater than or equal to %{num}"
14
-
15
- inclusion?: "%{name} must be one of: %{list}"
16
-
17
- int?: "%{name} must be an integer"
18
-
19
- key?: "%{name} is missing"
20
-
21
- lt?: "%{name} must be less than %{num} (%{value} was given)"
22
-
23
- lteq?: "%{name} must be less than or equal to %{num}"
24
-
25
- max_size?: "%{name} size cannot be greater than %{num}"
26
-
27
- min_size?: "%{name} size cannot be less than %{num}"
28
-
29
- nil?: "%{name} cannot be nil"
30
-
31
- size?:
32
- range: "%{name} size must be within %{left} - %{right}"
33
- default: "%{name} size must be %{num}"
34
-
35
- str?: "%{name} must be a string"
1
+ en:
2
+ dry_validation:
3
+ errors:
4
+ acceptance: "must accept %{key}"
@@ -1,25 +1,41 @@
1
- # coding: utf-8
2
- require File.expand_path('../lib/dry/validation/version', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ # this file is synced from dry-rb/template-gem project
4
+
5
+ lib = File.expand_path("lib", __dir__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+ require "dry/validation/version"
3
8
 
4
9
  Gem::Specification.new do |spec|
5
- spec.name = 'dry-validation'
6
- spec.version = Dry::Validation::VERSION
7
- spec.authors = ['Andy Holland', 'Piotr Solnica']
8
- spec.email = ['andyholland1991@aol.com', 'piotr.solnica@gmail.com']
9
- spec.summary = 'A simple validation library'
10
- spec.homepage = 'https://github.com/dryrb/dry-validation'
11
- spec.license = 'MIT'
12
-
13
- spec.files = `git ls-files -z`.split("\x0")
14
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
- spec.require_paths = ['lib']
17
-
18
- spec.add_runtime_dependency 'dry-configurable', '~> 0.1'
19
- spec.add_runtime_dependency 'dry-container', '~> 0.2', '>= 0.2.6'
20
- spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
21
-
22
- spec.add_development_dependency 'bundler'
23
- spec.add_development_dependency 'rake'
24
- spec.add_development_dependency 'rspec'
10
+ spec.name = "dry-validation"
11
+ spec.authors = ["Piotr Solnica"]
12
+ spec.email = ["piotr.solnica@gmail.com"]
13
+ spec.license = "MIT"
14
+ spec.version = Dry::Validation::VERSION.dup
15
+
16
+ spec.summary = "Validation library"
17
+ spec.description = spec.summary
18
+ spec.homepage = "https://dry-rb.org/gems/dry-validation"
19
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-validation.gemspec", "lib/**/*", "config/*.yml"]
20
+ spec.bindir = "bin"
21
+ spec.executables = []
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
25
+ spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-validation/blob/master/CHANGELOG.md"
26
+ spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-validation"
27
+ spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-validation/issues"
28
+
29
+ spec.required_ruby_version = ">= 2.7.0"
30
+
31
+ # to update dependencies edit project.yml
32
+ spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
33
+ spec.add_runtime_dependency "dry-container", "~> 0.7", ">= 0.7.1"
34
+ spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
35
+ spec.add_runtime_dependency "dry-initializer", "~> 3.0"
36
+ spec.add_runtime_dependency "dry-schema", "~> 1.9", ">= 1.9.1"
37
+
38
+ spec.add_development_dependency "bundler"
39
+ spec.add_development_dependency "rake"
40
+ spec.add_development_dependency "rspec"
25
41
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/schema/config"
4
+ require "dry/validation/macros"
5
+
6
+ module Dry
7
+ module Validation
8
+ # Configuration for contracts
9
+ #
10
+ # @see Contract#config
11
+ #
12
+ # @api public
13
+ class Config < Schema::Config
14
+ setting :macros, default: Macros::Container.new, constructor: :dup.to_proc
15
+
16
+ # @api private
17
+ def dup
18
+ config = super
19
+ config.macros = macros.dup
20
+ config
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "dry/core/constants"
5
+
6
+ module Dry
7
+ module Validation
8
+ include Dry::Core::Constants
9
+
10
+ DOT = "."
11
+
12
+ # Root path is used for base errors in hash representation of error messages
13
+ ROOT_PATH = [nil].freeze
14
+
15
+ # Path to the default errors locale file
16
+ DEFAULT_ERRORS_NAMESPACE = "dry_validation"
17
+
18
+ # Path to the default errors locale file
19
+ DEFAULT_ERRORS_PATH = Pathname(__FILE__).join("../../../../config/errors.yml").realpath.freeze
20
+
21
+ # Mapping for block kwarg options used by block_options
22
+ #
23
+ # @see Rule#block_options
24
+ BLOCK_OPTIONS_MAPPINGS = Hash.new { |_, key| key }.update(context: :_context).freeze
25
+
26
+ # Error raised when `rule` specifies one or more keys that the schema doesn't specify
27
+ InvalidKeysError = Class.new(StandardError)
28
+
29
+ # Error raised when a localized message was not found
30
+ MissingMessageError = Class.new(StandardError)
31
+
32
+ # Error raised when trying to define a schema in a contract class that already has a schema
33
+ DuplicateSchemaError = Class.new(StandardError)
34
+
35
+ # Error raised during initialization of a contract that has no schema defined
36
+ SchemaMissingError = Class.new(StandardError) do
37
+ # @api private
38
+ def initialize(klass)
39
+ super("#{klass} cannot be instantiated without a schema defined")
40
+ end
41
+ end
42
+ end
43
+ end