constrain 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b497524127f01a38cc3c6f4061e91e0cad65b587538d57f69b194a550d46bf1
4
- data.tar.gz: 95cff0709eb06ab088fee635c5629de99d16f521f9d24ea0a603ddb4d0968780
3
+ metadata.gz: ff3fb59b6d713b01843aa67e4e90855e58f99b1fcffa8ff27ae66b53987d9672
4
+ data.tar.gz: 98237076729ee99035e1af426308f12ef36963879950287f107486ae0485e061
5
5
  SHA512:
6
- metadata.gz: f843d4f4b653ab255f52d9c5188b3d9d72c0170e0f4af4522404e4d993b97f6629b0b61c665a9cc47f3fc89a22ca7f7beb9efd68dfdae186c5d1502b320004d7
7
- data.tar.gz: 70654e57d920e7f13a92394d57f7b5ddff2529ebe346507de201f47ce9aad77beef17992419dea84f1ba795b4de7d8443a65d3250b9a46298f8b1896d43dbeb4
6
+ metadata.gz: 533a2c7486903550fa42c3f349417130a8dd69642adf6d2e27599bd9f5e4b6be3fca0dcfcc58370cf4d64169952e06df5a0ad76603d424741f0c7846301f66ac
7
+ data.tar.gz: 95ee72d76e6ccfdd7faffd971214ecc6b171ab1a58debfd5a6a043a0764e8f154a910a7086399363a4bc88e94406a7a048f5efa32cadf5c1d8ded2e1725fcc37
@@ -1,3 +1,3 @@
1
1
  module Constrain
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/constrain.rb CHANGED
@@ -3,8 +3,12 @@ require "constrain/version"
3
3
  module Constrain
4
4
  # Raised if types doesn't match a class expression
5
5
  class MatchError < StandardError
6
- def initialize(value, exprs, message: nil, unwind: 0)
7
- super message || "Expected #{value.inspect} to match #{Constrain.fmt_exprs(exprs)}"
6
+ def initialize(value, exprs, message: nil, unwind: 0, not_argument: false, not_value: nil)
7
+ if not_argument
8
+ super message || "Expected #{value.inspect} to not equal #{not_value.inspect}"
9
+ else
10
+ super message || "Expected #{value.inspect} to match #{Constrain.fmt_exprs(exprs)}"
11
+ end
8
12
  end
9
13
  end
10
14
 
@@ -12,17 +16,6 @@ module Constrain
12
16
  base.extend ClassMethods
13
17
  end
14
18
 
15
- # See Constrain.constrain
16
- def constrain(value, *exprs)
17
- Constrain.do_constrain(value, *exprs)
18
- end
19
-
20
- # Like #constrain but returns true/false to indicate the result instead of
21
- # raising an exception
22
- def constrain?(value, *exprs)
23
- Constrain.do_constrain?(value, *exprs)
24
- end
25
-
26
19
  # :call-seq:
27
20
  # constrain(value, *class-expressions, unwind: 0)
28
21
  # constrain(value, *values, unwind: 0)
@@ -31,38 +24,41 @@ module Constrain
31
24
  # ArgumentError if the expression is invalid and a Constrain::MatchError if
32
25
  # the value doesn't match. The exception's backtrace skips :unwind number of
33
26
  # entries
34
- def self.constrain(value, *exprs)
35
- do_constrain(value, *exprs)
27
+ def self.constrain(value, *exprs, **opts)
28
+ do_constrain(value, *exprs, **opts)
36
29
  end
37
30
 
38
- # Return true if the value matches the class expression. Raises a
39
- # ArgumentError if the expression is invalid
40
- def self.constrain?(value, *exprs)
41
- do_constrain?(value, *exprs)
31
+ # See Constrain.constrain
32
+ def constrain(...) = Constrain.do_constrain(...)
33
+
34
+ # Like #constrain but returns true/false to indicate the result instead of
35
+ # raising an exception
36
+ def self.constrain?(value, *exprs, **opts)
37
+ do_constrain?(value, *exprs, **opts)
42
38
  end
43
39
 
40
+ # See Constrain.constrain?
41
+ def constrain?(...) = Constrain.do_constrain?(...)
42
+
44
43
  module ClassMethods
45
44
  # See Constrain.constrain
46
- def constrain(*args)
47
-
48
- Constrain.do_constrain(*args) end
45
+ def constrain(...) Constrain.do_constrain(...) end
49
46
 
50
47
  # See Constrain.constrain?
51
- def constrain?(*args) Constrain.do_constrain?(*args) end
48
+ def constrain?(...) Constrain.do_constrain?(...) end
52
49
  end
53
50
 
51
+ # :call-seq:
52
+ # do_constrain(value, *exprs, unwind: 0, message: nil, not: nil)
53
+ #
54
54
  # unwind is automatically incremented by one because ::do_constrain is always
55
55
  # called from one of the other constrain methods
56
56
  #
57
- def self.do_constrain(value, *exprs)
58
- if exprs.last.is_a?(Hash)
59
- unwind = (exprs.last.delete(:unwind) || 0) + 1
60
- message = exprs.last.delete(:message)
61
- !exprs.last.empty? or exprs.pop # Remove option hash if empty
62
- else
63
- unwind = 1
64
- message = nil
65
- end
57
+ def self.do_constrain(value, *exprs, unwind: 0, message: nil, **opts)
58
+ opts.keys.empty? || opts.keys == [:not] or raise ArgumentError
59
+ unwind += 1
60
+ not_argument = opts.key?(:not)
61
+ not_value = opts[:not]
66
62
 
67
63
  begin
68
64
  if exprs.empty?
@@ -71,6 +67,10 @@ module Constrain
71
67
  exprs.any? { |expr| Constrain.do_constrain_value?(value, expr) } or
72
68
  raise MatchError.new(value, exprs, message: message, unwind: unwind)
73
69
  end
70
+ !not_argument || value != not_value or
71
+ raise MatchError.new(
72
+ value, exprs, message: message, unwind: unwind, not_argument: true, not_value: not_value)
73
+
74
74
  rescue ArgumentError, Constrain::MatchError => ex
75
75
  ex.set_backtrace(caller[1 + unwind..-1])
76
76
  raise
@@ -78,11 +78,13 @@ module Constrain
78
78
  value
79
79
  end
80
80
 
81
- def self.do_constrain?(value, *exprs)
81
+ def self.do_constrain?(...)
82
82
  begin
83
- !exprs.empty? or raise ArgumentError, "Empty constraint"
84
- exprs.any? { |expr| Constrain.do_constrain_value?(value, expr) }
83
+ do_constrain(...)
84
+ rescue MatchError
85
+ return false
85
86
  end
87
+ true
86
88
  end
87
89
 
88
90
  def self.do_constrain_value?(value, expr)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: constrain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-17 00:00:00.000000000 Z
11
+ date: 2023-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov