validator_fn 0.1.6 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a18a2dee04cebf84a277132258a1456f981fe477467d041ea6c29e564051a74
4
- data.tar.gz: 2c82211054e4b07ee55f068dd87218b8f4d2da001889cd054d220be6346d84f0
3
+ metadata.gz: cecd9880750c518fcd26fd705b76ffeaf4604fb90af4bd60719ecf37a387d8ee
4
+ data.tar.gz: d04d0ef810ab4ac5ea7b8914690c1995ffdf913c8ad4a40c5bfa85ce5ce8a817
5
5
  SHA512:
6
- metadata.gz: d027d9af4b77d44e4b0dc9271faeb9bc89dc0e617439442f1858215ff06a8f806edac282379c1e28b176cc532522b3c5258aadc29c6745649930e2bfe6ac92ef
7
- data.tar.gz: 42385b0fbcdeb03906d81e4e4d32c29d6d19edcbb950586afc85553baba260823792e72e1f9f03fae5440e16d07160272996dacee50a2c971817dc8f68d0297e
6
+ metadata.gz: 52647b99fdac1ff9dcf399b96d4b5a5becac6748270795cb47f0caa11e1735217239108450418781bf933dabdc0accf3ef3eaf7c9b8feb9fc1bd5f3deabe34d9
7
+ data.tar.gz: 5c16a63c7a8f261cf8cf76af633dbc448975dd77cbe08074abf2dd8f77cca95b42baa3ce876c08d2f3186d52eee68edd1a94abea6b33440263e617364732d6a3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- validator_fn (0.1.6)
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.1.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,10 @@
1
1
  # ValidatorFn
2
2
 
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/).
3
+ ValidatorFn is a collection of very simple lambdas that can be used for validating/transforming
4
+ data structures. It makes use of currying to provide a very composable
5
+ DSL. To help you understand the concepts, I strongly advise reading [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 come from input, such as configuration files, JSON APIs, test results.
7
8
 
8
9
  ## Installation
9
10
 
@@ -23,30 +24,30 @@ Or install it yourself as:
23
24
 
24
25
  ## Usage
25
26
 
26
- ```
27
+ ```ruby
27
28
  require 'validator_fn'
28
29
  include ValidatorFn
29
30
  ```
30
31
 
31
- You can start validating type of an object.
32
+ You can start validating the type of an object.
32
33
 
33
- ```
34
+ ```ruby
34
35
  is_a.(String).(3)
35
36
  ```
36
37
 
37
- Note that parameters are curried. The first param of `is_a` is the Ruby class that you want to check the last parameter against.
38
- In the previous example, aValidatorFn::Error`exception will be raised.
38
+ Note that parameters are curried. The first param of `is_a` is the Ruby class you want to check the last parameter against.
39
+ In the previous example, a `ValidatorFn::Error`exception will be raised.
39
40
 
40
- However if you send a valid entry as the second parameter, it will return that last parameter.
41
+ However, setting a valid entry as the second parameter will return that last parameter.
41
42
 
42
- ```
43
+ ```ruby
43
44
  is_a.(String).("Joe")
44
45
  # => "Joe"
45
46
  ```
46
47
 
47
48
  This allows chaining lambdas:
48
49
 
49
- ```
50
+ ```ruby
50
51
  to_int = is_a.(String) >> -> a { Integer(a) }
51
52
 
52
53
  to_int.("12")
@@ -56,25 +57,91 @@ to_int.("asdf") # will raise an exception
56
57
 
57
58
  You can validate a hash:
58
59
 
59
- ```
60
+ ```ruby
60
61
  user = hash_of.({name: is_a.(String), age: to_int})
61
62
  user.({name: "", age: "234"})
62
63
  ```
63
64
 
64
- Since we are using curried lambdas, you can compose validators as you which.
65
+ Since we are using curried lambdas, you can compose validators as you which.
65
66
 
66
- ```
67
- postal_code = -> a {
67
+ ```ruby
68
+ postal_code = -> a {
68
69
  invalid.("Invalid postal code: #{a}") unless a =~ /[a-z]\d[a-z]\s*\d[a-z]\d/i
69
70
  a
70
71
  }
71
- contact = hash_of.(user: user,
72
- address: hash_of.({ street_number: is_a.(Integer),
72
+ contact = hash_of.(user: user,
73
+ address: hash_of.({ street_number: is_a.(Integer),
73
74
  postal_code: postal_code}))
74
75
  ```
75
76
 
76
- This is a very simple library (100 lines of code) that can be extended as you which by
77
- creating your own lambdas.
77
+ This very simple library (100 lines of code) can be extended easily by creating new lambdas.
78
+
79
+ ## Casting
80
+
81
+ You can also apply converter functions to the structure.
82
+
83
+ ```ruby
84
+ user = { name: "Joe", created_at: "2020-01-03" }
85
+ to_date = ->str { Date.parse(str) }
86
+ user_validator = hash_of.(name: is_a.(String),
87
+ created_at: is_a.(String) >> to_date)
88
+
89
+ user_validator.(user)
90
+ # => {:name=>"Joe", :created_at=>#<Date: 2020-01-03 ((2458852j,0s,0n),+0s,2299161j)>}
91
+ ```
92
+
93
+ This makes it very useful for processing JSON payloads.
94
+
95
+ ## Code generation
96
+
97
+ You can generate validator code from existing structure:
98
+
99
+ ```ruby
100
+ require 'openuri'
101
+ require "json"
102
+ struct = JSON.parse(URI.open("https://api.github.com/users/defunkt").read)
103
+
104
+ require "validator_fn"
105
+
106
+ # Generate unformatted code
107
+ code = ValidatorFn.generate_validator.(struct)
108
+
109
+ # You can reformat it using a code formatter
110
+ require "rufo"
111
+ puts Rufo.format(code)
112
+ hash_of.({ "login" => is_a.(String),
113
+ "id" => is_a.(Integer),
114
+ "node_id" => is_a.(String),
115
+ "avatar_url" => is_a.(String),
116
+ "gravatar_id" => is_a.(String),
117
+ "url" => is_a.(String),
118
+ "html_url" => is_a.(String),
119
+ "followers_url" => is_a.(String),
120
+ "following_url" => is_a.(String),
121
+ "gists_url" => is_a.(String),
122
+ "starred_url" => is_a.(String),
123
+ "subscriptions_url" => is_a.(String),
124
+ "organizations_url" => is_a.(String),
125
+ "repos_url" => is_a.(String),
126
+ "events_url" => is_a.(String),
127
+ "received_events_url" => is_a.(String),
128
+ "type" => is_a.(String),
129
+ "site_admin" => is_a_bool,
130
+ "name" => is_a.(String),
131
+ "company" => any,
132
+ "blog" => is_a.(String),
133
+ "location" => any,
134
+ "email" => any,
135
+ "hireable" => any,
136
+ "bio" => is_a.(String),
137
+ "twitter_username" => any,
138
+ "public_repos" => is_a.(Integer),
139
+ "public_gists" => is_a.(Integer),
140
+ "followers" => is_a.(Integer),
141
+ "following" => is_a.(Integer),
142
+ "created_at" => is_a.(String),
143
+ "updated_at" => is_a.(String) })
144
+ ```
78
145
 
79
146
  ## Development
80
147
 
@@ -86,7 +153,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
86
153
 
87
154
  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
155
 
89
-
90
156
  ## License
91
157
 
92
158
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -94,6 +160,3 @@ The gem is available as open source under the terms of the [MIT License](https:/
94
160
  ## Code of Conduct
95
161
 
96
162
  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
- 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,29 @@
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
+
24
+ class MissingKey < Error
25
+ def initialize(key)
26
+ super("Missing field #{key}")
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module ValidatorFn
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.8"
3
3
  end
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,11 +36,19 @@ 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)|
65
- memo[key] ||= fn.(hash[key]) if hash[key]
43
+ value = hash.fetch(key, :missing_field)
44
+ if value == :missing_field
45
+ raise MissingKey.new(key)
46
+ else
47
+ memo[key] = fn.(hash[key]) if hash[key]
48
+ end
66
49
  memo
50
+ rescue MissingKey => e
51
+ raise
67
52
  rescue Error => e
68
53
  invalid.("Invalid value for #{key.inspect} key.")
69
54
  end
@@ -97,6 +82,10 @@ module ValidatorFn
97
82
  "hash_of.({ #{inner} })"
98
83
  when Array
99
84
  "array_of.( #{generate_validator.(a.first)} )"
85
+ when TrueClass
86
+ "is_a_bool"
87
+ when FalseClass
88
+ "is_a_bool"
100
89
  else
101
90
  "is_a.(#{a.class})"
102
91
  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.6
4
+ version: 0.2.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: 2021-12-12 00:00:00.000000000 Z
11
+ date: 2022-06-30 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.4
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