dry-schema 0.1.0 → 0.1.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/lib/dry/schema.rb +1 -1
- data/lib/dry/schema/dsl.rb +1 -1
- data/lib/dry/schema/key_coercer.rb +3 -1
- data/lib/dry/schema/message.rb +1 -1
- data/lib/dry/schema/message_compiler.rb +1 -1
- data/lib/dry/schema/messages/abstract.rb +5 -4
- data/lib/dry/schema/messages/template.rb +66 -0
- data/lib/dry/schema/path.rb +55 -0
- data/lib/dry/schema/processor.rb +2 -2
- data/lib/dry/schema/result.rb +6 -4
- data/lib/dry/schema/value_coercer.rb +2 -0
- data/lib/dry/schema/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebc7203aa64419493d5557a5228e8ae17da67a89b7dab86556897aad7856138e
|
4
|
+
data.tar.gz: '083cad2ab1b35ecfac75a5d37a868f36145cce8ea31bf03dc10b3ad84233b498'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0db3366b58c3fd06ad10958de4215ae5b2ff67f244873ff8b48b96da9bfcf08678a06ef3302099862891630b825596c6a4adfecac9140e8e5045ca7acc200b34
|
7
|
+
data.tar.gz: 04e3fa2ee8d50aaac7c6bcdaacb1611252ce06af397499cf0fbc0ed21fb33e62c55b9ab0179b4df9160bbd0efe1c6bed1c60ac628c06f23f992879df8c6326ed
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# 0.1.1 2019-02-17
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
- `Result#error?` supports checking nested errors too ie`result.error?('user.address')` (solnic)
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
|
9
|
+
- Fix issues with templates and invalid tokens (issue #27) (solnic)
|
10
|
+
- Fix Ruby warnings (flash-gordon)
|
11
|
+
|
12
|
+
### Internal
|
13
|
+
|
14
|
+
- Key and value coercers are now equalizable (flash-gordon)
|
15
|
+
|
16
|
+
[Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-schema/compare/v0.1.0...v0.1.1)
|
17
|
+
|
1
18
|
# 0.1.0 2019-01-30
|
2
19
|
|
3
20
|
Initial release.
|
data/lib/dry/schema.rb
CHANGED
data/lib/dry/schema/dsl.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'dry/core/cache'
|
2
|
+
require 'dry/equalizer'
|
2
3
|
|
3
4
|
module Dry
|
4
5
|
module Schema
|
@@ -7,6 +8,7 @@ module Dry
|
|
7
8
|
# @api private
|
8
9
|
class KeyCoercer
|
9
10
|
extend Dry::Core::Cache
|
11
|
+
include ::Dry::Equalizer(:key_map, :coercer)
|
10
12
|
|
11
13
|
TO_SYM = :to_sym.to_proc.freeze
|
12
14
|
|
@@ -26,7 +28,7 @@ module Dry
|
|
26
28
|
def initialize(key_map, &coercer)
|
27
29
|
@key_map = key_map.coercible(&coercer)
|
28
30
|
end
|
29
|
-
|
31
|
+
|
30
32
|
# @api private
|
31
33
|
def call(source)
|
32
34
|
key_map.write(Hash(source))
|
data/lib/dry/schema/message.rb
CHANGED
@@ -164,7 +164,7 @@ module Dry
|
|
164
164
|
|
165
165
|
# @api private
|
166
166
|
def message_text(rule, template, tokens, opts)
|
167
|
-
text = template
|
167
|
+
text = template[template.data(tokens)]
|
168
168
|
|
169
169
|
if full?
|
170
170
|
rule_name = rule ? (messages.rule(rule, opts) || rule) : (opts[:name] || opts[:path].last)
|
@@ -4,6 +4,7 @@ require 'dry/equalizer'
|
|
4
4
|
require 'dry/configurable'
|
5
5
|
|
6
6
|
require 'dry/schema/constants'
|
7
|
+
require 'dry/schema/messages/template'
|
7
8
|
|
8
9
|
module Dry
|
9
10
|
module Schema
|
@@ -69,15 +70,15 @@ module Dry
|
|
69
70
|
get(path, options) if key?(path, options)
|
70
71
|
end
|
71
72
|
|
72
|
-
# Retrieve a message
|
73
|
+
# Retrieve a message template
|
73
74
|
#
|
74
|
-
# @return [
|
75
|
+
# @return [Template]
|
75
76
|
#
|
76
77
|
# @api public
|
77
78
|
def call(*args)
|
78
79
|
cache.fetch_or_store(args.hash) do
|
79
80
|
path, opts = lookup(*args)
|
80
|
-
get(path, opts) if path
|
81
|
+
Template[get(path, opts)] if path
|
81
82
|
end
|
82
83
|
end
|
83
84
|
alias_method :[], :call
|
@@ -96,7 +97,7 @@ module Dry
|
|
96
97
|
|
97
98
|
tokens[:path] = options[:rule] || Array(options[:path]).join(DOT)
|
98
99
|
|
99
|
-
opts = options.
|
100
|
+
opts = options.select { |k, _| !config.lookup_options.include?(k) }
|
100
101
|
|
101
102
|
path = lookup_paths(tokens).detect do |key|
|
102
103
|
key?(key, opts) && get(key, opts).is_a?(String)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'dry/equalizer'
|
2
|
+
|
3
|
+
require 'dry/schema/constants'
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Schema
|
7
|
+
module Messages
|
8
|
+
# Template wraps a string with interpolation tokens and defines evaluator function
|
9
|
+
# dynamically
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class Template
|
13
|
+
include Dry::Equalizer(:text)
|
14
|
+
|
15
|
+
TOKEN_REGEXP = /%{([\w\d]*)}/
|
16
|
+
|
17
|
+
# !@attribute [r] text
|
18
|
+
# @return [String]
|
19
|
+
attr_reader :text
|
20
|
+
|
21
|
+
# !@attribute [r] tokens
|
22
|
+
# @return [Hash]
|
23
|
+
attr_reader :tokens
|
24
|
+
|
25
|
+
# !@attribute [r] evaluator
|
26
|
+
# @return [Proc]
|
27
|
+
attr_reader :evaluator
|
28
|
+
|
29
|
+
# @api private
|
30
|
+
def self.[](input)
|
31
|
+
new(*parse(input))
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api private
|
35
|
+
def self.parse(input)
|
36
|
+
tokens = input.scan(TOKEN_REGEXP).flatten(1).map(&:to_sym)
|
37
|
+
text = input.gsub('%', '#')
|
38
|
+
|
39
|
+
evaluator = <<-RUBY.strip
|
40
|
+
-> (#{tokens.map { |token| "#{token}:" }.join(", ")}) { "#{text}" }
|
41
|
+
RUBY
|
42
|
+
|
43
|
+
[text, tokens, eval(evaluator, binding, __FILE__, __LINE__ - 3)]
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def initialize(text, tokens, evaluator)
|
48
|
+
@text = text
|
49
|
+
@tokens = tokens
|
50
|
+
@evaluator = evaluator
|
51
|
+
end
|
52
|
+
|
53
|
+
# @api private
|
54
|
+
def data(input)
|
55
|
+
tokens.each_with_object({}) { |k, h| h[k] = input[k] }
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def call(data = EMPTY_HASH)
|
60
|
+
data.empty? ? evaluator.() : evaluator.(data)
|
61
|
+
end
|
62
|
+
alias_method :[], :call
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'dry/schema/constants'
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Schema
|
5
|
+
# Path represents a list of keys in a hash
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class Path
|
9
|
+
# !@attribute [r] keys
|
10
|
+
# @return [Array<Symbol>]
|
11
|
+
attr_reader :keys
|
12
|
+
|
13
|
+
# Coerce a spec into a path object
|
14
|
+
#
|
15
|
+
# @param [Symbol, String, Hash, Array<Symbol>] spec
|
16
|
+
#
|
17
|
+
# @return [Path]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
def self.[](spec)
|
21
|
+
case spec
|
22
|
+
when Symbol, Array
|
23
|
+
new(Array[*spec])
|
24
|
+
when String
|
25
|
+
new(spec.split(DOT).map(&:to_sym))
|
26
|
+
when Hash
|
27
|
+
new(keys_from_hash(spec))
|
28
|
+
when self
|
29
|
+
spec
|
30
|
+
else
|
31
|
+
raise ArgumentError, '+spec+ must be either a Symbol, Array or Hash'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Extract a list of keys from a hash
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
def self.keys_from_hash(hash)
|
39
|
+
hash.inject([]) { |a, (k, v)|
|
40
|
+
v.is_a?(Hash) ? a.concat([k, *keys_from_hash(v)]) : a.concat([k, v])
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# @api private
|
45
|
+
def initialize(keys)
|
46
|
+
@keys = keys
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
def ==(other)
|
51
|
+
keys == Path[other].keys
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/dry/schema/processor.rb
CHANGED
@@ -15,7 +15,7 @@ module Dry
|
|
15
15
|
# 1. Prepare input hash using a key map
|
16
16
|
# 2. Apply pre-coercion filtering rules (optional step, used only when `filter` was used)
|
17
17
|
# 3. Apply value coercions based on type specifications
|
18
|
-
# 4. Apply rules
|
18
|
+
# 4. Apply rules
|
19
19
|
#
|
20
20
|
# @see Params
|
21
21
|
# @see JSON
|
@@ -51,7 +51,7 @@ module Dry
|
|
51
51
|
#
|
52
52
|
# @api private
|
53
53
|
def self.definition
|
54
|
-
@__definition__
|
54
|
+
@__definition__ ||= nil
|
55
55
|
end
|
56
56
|
|
57
57
|
# Build a new processor object
|
data/lib/dry/schema/result.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'dry/initializer'
|
2
2
|
require 'dry/equalizer'
|
3
3
|
|
4
|
+
require 'dry/schema/path'
|
5
|
+
|
4
6
|
module Dry
|
5
7
|
module Schema
|
6
8
|
# Processing result
|
@@ -66,15 +68,15 @@ module Dry
|
|
66
68
|
output.key?(name)
|
67
69
|
end
|
68
70
|
|
69
|
-
# Check if
|
71
|
+
# Check if there's an error for the provided spec
|
70
72
|
#
|
71
|
-
# @param [Symbol] name
|
73
|
+
# @param [Symbol, Hash<Symbol=>Symbol>] name
|
72
74
|
#
|
73
75
|
# @return [Boolean]
|
74
76
|
#
|
75
77
|
# @api public
|
76
|
-
def error?(
|
77
|
-
|
78
|
+
def error?(spec)
|
79
|
+
message_set.any? { |msg| Path[spec] == msg.path }
|
78
80
|
end
|
79
81
|
|
80
82
|
# Check if the result is successful
|
data/lib/dry/schema/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -216,8 +216,10 @@ files:
|
|
216
216
|
- lib/dry/schema/messages/abstract.rb
|
217
217
|
- lib/dry/schema/messages/i18n.rb
|
218
218
|
- lib/dry/schema/messages/namespaced.rb
|
219
|
+
- lib/dry/schema/messages/template.rb
|
219
220
|
- lib/dry/schema/messages/yaml.rb
|
220
221
|
- lib/dry/schema/params.rb
|
222
|
+
- lib/dry/schema/path.rb
|
221
223
|
- lib/dry/schema/predicate.rb
|
222
224
|
- lib/dry/schema/predicate_inferrer.rb
|
223
225
|
- lib/dry/schema/predicate_registry.rb
|
@@ -248,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
248
250
|
- !ruby/object:Gem::Version
|
249
251
|
version: '0'
|
250
252
|
requirements: []
|
251
|
-
rubygems_version: 3.0.
|
253
|
+
rubygems_version: 3.0.1
|
252
254
|
signing_key:
|
253
255
|
specification_version: 4
|
254
256
|
summary: Schema coercion and validation
|