validator_fn 0.1.4 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94899eae6f032c863b53262ae16bee3c17bfd1085db3add84d77bd889a2d537b
4
- data.tar.gz: 513ccc5a96f2eb2ff5aed7930288ebba10e66075540f61dc2b7fedb1739aa9e0
3
+ metadata.gz: dbf0665436aeda62b487528bb8f8f85777c45a357c4cf34884600a14273f289d
4
+ data.tar.gz: 0ba29a6cf3b5d453f3561f8e9c3f205c060d088226c83f494ff7a269dc672734
5
5
  SHA512:
6
- metadata.gz: d7f0cc3a38e7a9c6611eee9205e20aba7b5adcf820170332f81116326294e633958df750d596eec5c89161d8d2a045d6511223adea4b9bc3e42f89e198db0e61
7
- data.tar.gz: 7d8a6aa61a9c8246a9a8762b94830270f6b0330a24f10bcd5b836ac074998fe6a589eeb943e58c3d3def890d0912df966da3543614a00aa3572700e4663cb540
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)
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,8 +1,11 @@
1
1
  # ValidatorFn
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/validator_fn`. To experiment with that code, run `bin/console` for an interactive prompt.
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/).
4
6
 
5
- TODO: Delete this and the text above, and describe your gem
7
+ It can be very useful for validating structures that comes from input, such as configuration files,
8
+ JSON apis, test result.
6
9
 
7
10
  ## Installation
8
11
 
@@ -22,7 +25,125 @@ Or install it yourself as:
22
25
 
23
26
  ## Usage
24
27
 
25
- TODO: Write usage instructions here
28
+ ```
29
+ require 'validator_fn'
30
+ include ValidatorFn
31
+ ```
32
+
33
+ You can start validating type of an object.
34
+
35
+ ```
36
+ is_a.(String).(3)
37
+ ```
38
+
39
+ Note that parameters are curried. The first param of `is_a` is the Ruby class that you want to check the last parameter against.
40
+ In the previous example, aValidatorFn::Error`exception will be raised.
41
+
42
+ However if you send a valid entry as the second parameter, it will return that last parameter.
43
+
44
+ ```
45
+ is_a.(String).("Joe")
46
+ # => "Joe"
47
+ ```
48
+
49
+ This allows chaining lambdas:
50
+
51
+ ```
52
+ to_int = is_a.(String) >> -> a { Integer(a) }
53
+
54
+ to_int.("12")
55
+ # => 12
56
+ to_int.("asdf") # will raise an exception
57
+ ```
58
+
59
+ You can validate a hash:
60
+
61
+ ```
62
+ user = hash_of.({name: is_a.(String), age: to_int})
63
+ user.({name: "", age: "234"})
64
+ ```
65
+
66
+ Since we are using curried lambdas, you can compose validators as you which.
67
+
68
+ ```
69
+ postal_code = -> a {
70
+ invalid.("Invalid postal code: #{a}") unless a =~ /[a-z]\d[a-z]\s*\d[a-z]\d/i
71
+ a
72
+ }
73
+ contact = hash_of.(user: user,
74
+ address: hash_of.({ street_number: is_a.(Integer),
75
+ postal_code: postal_code}))
76
+ ```
77
+
78
+ This is a very simple library (100 lines of code) that can be extended as you which by
79
+ creating your own lambdas.
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
+ ```
26
147
 
27
148
  ## Development
28
149
 
@@ -34,7 +155,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
34
155
 
35
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).
36
157
 
37
-
38
158
  ## License
39
159
 
40
160
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -42,3 +162,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
42
162
  ## Code of Conduct
43
163
 
44
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).
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).
@@ -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
@@ -1,3 +1,3 @@
1
1
  module ValidatorFn
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.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
@@ -56,9 +33,10 @@ module ValidatorFn
56
33
  end
57
34
  }.curry
58
35
  @@any = ->a { a }
59
- @@is_nil = ->a { invalid.("Should be nil") unless a.nil?; a }
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)|
@@ -92,11 +70,15 @@ module ValidatorFn
92
70
  "any"
93
71
  when Hash
94
72
  inner = a.map do |k, v|
95
- %{"#{k}" => #{generate_validator.(v)}}
73
+ %{#{k.inspect} => #{generate_validator.(v)}}
96
74
  end.join(",\n ")
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
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: 2020-12-29 00:00:00.000000000 Z
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.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