validator_fn 0.1.7 → 0.1.8
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/Gemfile.lock +2 -2
- data/README.md +77 -11
- data/lib/validator_fn/error.rb +23 -0
- data/lib/validator_fn/version.rb +1 -1
- data/lib/validator_fn.rb +7 -25
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbf0665436aeda62b487528bb8f8f85777c45a357c4cf34884600a14273f289d
|
4
|
+
data.tar.gz: 0ba29a6cf3b5d453f3561f8e9c3f205c060d088226c83f494ff7a269dc672734
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de5d94c98746fd64ecb55f05e658ec434f57c8e518d16bb817ef39e4c56b53cd7130c52ab3ee69dddd5d8b853830dd271374d29c4ac6573576b9cdaf9287c80b
|
7
|
+
data.tar.gz: cfd9b2aab1a51bae15f335fc74e0970bf406d16f0e522ce3eb239176e0814a59bf0be37f13c4753bb0e2193c828634c7e6de7aeda7f323eb92eede177c3ad8ce
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
validator_fn (0.1.
|
4
|
+
validator_fn (0.1.8)
|
5
5
|
fn_reader
|
6
6
|
|
7
7
|
GEM
|
@@ -9,7 +9,7 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
coderay (1.1.3)
|
11
11
|
diff-lcs (1.4.4)
|
12
|
-
fn_reader (0.
|
12
|
+
fn_reader (0.2.0)
|
13
13
|
method_source (0.9.2)
|
14
14
|
pry (0.12.2)
|
15
15
|
coderay (~> 1.1.0)
|
data/README.md
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# ValidatorFn
|
2
2
|
|
3
|
-
ValidatorFn is a collection of very simple lambdas that can be used for validating/transforming
|
4
|
-
data structures.
|
5
|
-
DSL. To help you understand the concepts it is stongly advised to read [this blog post.](http://blog.martinosis.com/blog/simple-functional-strong-params-in-ruby/).
|
3
|
+
ValidatorFn is a collection of very simple lambdas that can be used for validating/transforming
|
4
|
+
data structures. It makes use of currying in order to provide a very composable
|
5
|
+
DSL. To help you understand the concepts it is stongly advised to read [this blog post.](http://blog.martinosis.com/blog/simple-functional-strong-params-in-ruby/).
|
6
6
|
|
7
|
+
It can be very useful for validating structures that comes from input, such as configuration files,
|
8
|
+
JSON apis, test result.
|
7
9
|
|
8
10
|
## Installation
|
9
11
|
|
@@ -28,7 +30,7 @@ require 'validator_fn'
|
|
28
30
|
include ValidatorFn
|
29
31
|
```
|
30
32
|
|
31
|
-
You can start validating type of an object.
|
33
|
+
You can start validating type of an object.
|
32
34
|
|
33
35
|
```
|
34
36
|
is_a.(String).(3)
|
@@ -61,21 +63,88 @@ user = hash_of.({name: is_a.(String), age: to_int})
|
|
61
63
|
user.({name: "", age: "234"})
|
62
64
|
```
|
63
65
|
|
64
|
-
Since we are using curried lambdas, you can compose validators as you which.
|
66
|
+
Since we are using curried lambdas, you can compose validators as you which.
|
65
67
|
|
66
68
|
```
|
67
|
-
postal_code = -> a {
|
69
|
+
postal_code = -> a {
|
68
70
|
invalid.("Invalid postal code: #{a}") unless a =~ /[a-z]\d[a-z]\s*\d[a-z]\d/i
|
69
71
|
a
|
70
72
|
}
|
71
|
-
contact = hash_of.(user: user,
|
72
|
-
address: hash_of.({ street_number: is_a.(Integer),
|
73
|
+
contact = hash_of.(user: user,
|
74
|
+
address: hash_of.({ street_number: is_a.(Integer),
|
73
75
|
postal_code: postal_code}))
|
74
76
|
```
|
75
77
|
|
76
78
|
This is a very simple library (100 lines of code) that can be extended as you which by
|
77
79
|
creating your own lambdas.
|
78
80
|
|
81
|
+
## Casting
|
82
|
+
|
83
|
+
You can also apply converter functions to the structure.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
user = { name: "Joe", created_at: "2020-01-03" }
|
87
|
+
to_date = ->str { Date.parse(str) }
|
88
|
+
user_validator = hash_of.(name: is_a.(String),
|
89
|
+
created_at: is_a.(String) >> to_date)
|
90
|
+
|
91
|
+
user_validator.(user)
|
92
|
+
# => {:name=>"Joe", :created_at=>#<Date: 2020-01-03 ((2458852j,0s,0n),+0s,2299161j)>}
|
93
|
+
```
|
94
|
+
|
95
|
+
This makes it very useful processing JSON payloads.
|
96
|
+
|
97
|
+
## Code generation
|
98
|
+
|
99
|
+
You can generate validator code from existing structure:
|
100
|
+
|
101
|
+
```
|
102
|
+
require 'openuri'
|
103
|
+
require "json"
|
104
|
+
struct = JSON.parse(URI.open("https://api.github.com/users/defunkt").read)
|
105
|
+
|
106
|
+
require_relative "validator_fn"
|
107
|
+
|
108
|
+
# Generate unformatted code
|
109
|
+
code = ValidatorFn.generate_validator.(struct)
|
110
|
+
|
111
|
+
# You can reformat it using a code formatter
|
112
|
+
require "rufo"
|
113
|
+
puts Rufo.format(code)
|
114
|
+
hash_of.({ "login" => is_a.(String),
|
115
|
+
"id" => is_a.(Integer),
|
116
|
+
"node_id" => is_a.(String),
|
117
|
+
"avatar_url" => is_a.(String),
|
118
|
+
"gravatar_id" => is_a.(String),
|
119
|
+
"url" => is_a.(String),
|
120
|
+
"html_url" => is_a.(String),
|
121
|
+
"followers_url" => is_a.(String),
|
122
|
+
"following_url" => is_a.(String),
|
123
|
+
"gists_url" => is_a.(String),
|
124
|
+
"starred_url" => is_a.(String),
|
125
|
+
"subscriptions_url" => is_a.(String),
|
126
|
+
"organizations_url" => is_a.(String),
|
127
|
+
"repos_url" => is_a.(String),
|
128
|
+
"events_url" => is_a.(String),
|
129
|
+
"received_events_url" => is_a.(String),
|
130
|
+
"type" => is_a.(String),
|
131
|
+
"site_admin" => is_a_bool,
|
132
|
+
"name" => is_a.(String),
|
133
|
+
"company" => any,
|
134
|
+
"blog" => is_a.(String),
|
135
|
+
"location" => any,
|
136
|
+
"email" => any,
|
137
|
+
"hireable" => any,
|
138
|
+
"bio" => is_a.(String),
|
139
|
+
"twitter_username" => any,
|
140
|
+
"public_repos" => is_a.(Integer),
|
141
|
+
"public_gists" => is_a.(Integer),
|
142
|
+
"followers" => is_a.(Integer),
|
143
|
+
"following" => is_a.(Integer),
|
144
|
+
"created_at" => is_a.(String),
|
145
|
+
"updated_at" => is_a.(String) })
|
146
|
+
```
|
147
|
+
|
79
148
|
## Development
|
80
149
|
|
81
150
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -86,7 +155,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
86
155
|
|
87
156
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/validator_fn. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/validator_fn/blob/master/CODE_OF_CONDUCT.md).
|
88
157
|
|
89
|
-
|
90
158
|
## License
|
91
159
|
|
92
160
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -95,5 +163,3 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
95
163
|
|
96
164
|
Everyone interacting in the ValidatorFn project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/validator_fn/blob/master/CODE_OF_CONDUCT.md).
|
97
165
|
Everyone interacting in the ValidatorFn project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/validator_fn/blob/master/CODE_OF_CONDUCT.md).
|
98
|
-
Everyone interacting in the ValidatorFn project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/validator_fn/blob/master/CODE_OF_CONDUCT.md).
|
99
|
-
Everyone interacting in the ValidatorFn project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/validator_fn/blob/master/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ValidatorFn
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :my_msg
|
4
|
+
|
5
|
+
def initialize(msg)
|
6
|
+
@my_msg = msg
|
7
|
+
super(msg)
|
8
|
+
end
|
9
|
+
|
10
|
+
def message(indent = 0)
|
11
|
+
if cause
|
12
|
+
cause_msg = if cause.kind_of?(Error)
|
13
|
+
cause.message(indent + 1)
|
14
|
+
else
|
15
|
+
cause.message
|
16
|
+
end
|
17
|
+
my_msg + "\n" + (" " * (indent + 1)) + cause_msg
|
18
|
+
else
|
19
|
+
my_msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/validator_fn/version.rb
CHANGED
data/lib/validator_fn.rb
CHANGED
@@ -1,33 +1,10 @@
|
|
1
1
|
require "validator_fn/version"
|
2
|
+
require "validator_fn/error"
|
2
3
|
require "fn_reader"
|
3
4
|
|
4
5
|
module ValidatorFn
|
5
|
-
class Error < StandardError; end
|
6
|
-
|
7
6
|
fn_reader :something, :matches, :either, :array_of, :any, :is_nil,
|
8
|
-
:maybe, :present, :is_a, :int, :hash_of, :invalid, :generate_validator, :handle_error, :error_str, :apply
|
9
|
-
|
10
|
-
class Error < StandardError
|
11
|
-
attr_reader :my_msg
|
12
|
-
|
13
|
-
def initialize(msg)
|
14
|
-
@my_msg = msg
|
15
|
-
super(msg)
|
16
|
-
end
|
17
|
-
|
18
|
-
def message(indent = 0)
|
19
|
-
if cause
|
20
|
-
cause_msg = if cause.kind_of?(Error)
|
21
|
-
cause.message(indent + 1)
|
22
|
-
else
|
23
|
-
cause.message
|
24
|
-
end
|
25
|
-
my_msg + "\n" + (" " * (indent + 1)) + cause_msg
|
26
|
-
else
|
27
|
-
my_msg
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
7
|
+
:maybe, :present, :is_a, :is_a_bool, :int, :hash_of, :invalid, :generate_validator, :handle_error, :error_str, :apply
|
31
8
|
|
32
9
|
@@apply = ->fn, a {
|
33
10
|
begin
|
@@ -59,6 +36,7 @@ module ValidatorFn
|
|
59
36
|
@@is_nil = ->a { invalid.("Should be nil but was #{a}") unless a.nil?; a }
|
60
37
|
@@maybe = either.(is_nil)
|
61
38
|
@@is_a = ->klass, a { invalid.("Expected type #{klass}, got #{a.inspect}") unless a.is_a?(klass); a }.curry
|
39
|
+
@@is_a_bool = ->a { invalid.("Expected bool, got #{a.inspect}") unless a == true || a == false; a }.curry
|
62
40
|
@@hash_of = ->fields, hash {
|
63
41
|
hash ||= {}
|
64
42
|
fields.reduce({}) do |memo, (key, fn)|
|
@@ -97,6 +75,10 @@ module ValidatorFn
|
|
97
75
|
"hash_of.({ #{inner} })"
|
98
76
|
when Array
|
99
77
|
"array_of.( #{generate_validator.(a.first)} )"
|
78
|
+
when TrueClass
|
79
|
+
"is_a_bool"
|
80
|
+
when FalseClass
|
81
|
+
"is_a_bool"
|
100
82
|
else
|
101
83
|
"is_a.(#{a.class})"
|
102
84
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validator_fn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Chabot
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fn_reader
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- bin/console
|
44
44
|
- bin/setup
|
45
45
|
- lib/validator_fn.rb
|
46
|
+
- lib/validator_fn/error.rb
|
46
47
|
- lib/validator_fn/version.rb
|
47
48
|
- validator_fn.gemspec
|
48
49
|
homepage: https://github.com/martinos/validator_fn
|
@@ -66,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
67
|
- !ruby/object:Gem::Version
|
67
68
|
version: '0'
|
68
69
|
requirements: []
|
69
|
-
rubygems_version: 3.1.
|
70
|
+
rubygems_version: 3.1.2
|
70
71
|
signing_key:
|
71
72
|
specification_version: 4
|
72
73
|
summary: Series of lambdas for validating Ruby structures
|