dry-schema 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|