striuct 0.6.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE.txt +21 -0
  3. data/README.md +44 -60
  4. data/lib/striuct/{requirements.rb → bootstrap.rb} +6 -2
  5. data/lib/striuct/classmethods/README.md +2 -2
  6. data/lib/striuct/classmethods/adjustment.rb +77 -13
  7. data/lib/striuct/classmethods/attributes.rb +94 -92
  8. data/lib/striuct/classmethods/conflict_management.rb +109 -106
  9. data/lib/striuct/classmethods/constructor.rb +55 -65
  10. data/lib/striuct/classmethods/copy.rb +45 -43
  11. data/lib/striuct/classmethods/default.rb +23 -21
  12. data/lib/striuct/classmethods/enum.rb +46 -44
  13. data/lib/striuct/classmethods/fix.rb +23 -21
  14. data/lib/striuct/classmethods/hashdeepdupulicatable.rb +15 -15
  15. data/lib/striuct/classmethods/inner.rb +57 -55
  16. data/lib/striuct/classmethods/length.rb +12 -10
  17. data/lib/striuct/classmethods/macro.rb +99 -106
  18. data/lib/striuct/classmethods/names.rb +69 -65
  19. data/lib/striuct/classmethods/predicate.rb +131 -129
  20. data/lib/striuct/classmethods/requirements.rb +2 -2
  21. data/lib/striuct/classmethods/to_struct.rb +21 -18
  22. data/lib/striuct/classmethods/validation.rb +15 -13
  23. data/lib/striuct/instancemethods/README.md +2 -2
  24. data/lib/striuct/instancemethods/assign.rb +29 -27
  25. data/lib/striuct/instancemethods/cast.rb +28 -26
  26. data/lib/striuct/instancemethods/compare.rb +26 -24
  27. data/lib/striuct/instancemethods/default.rb +31 -29
  28. data/lib/striuct/instancemethods/delegate_class_methods.rb +35 -33
  29. data/lib/striuct/instancemethods/enum.rb +86 -84
  30. data/lib/striuct/instancemethods/getter.rb +39 -37
  31. data/lib/striuct/instancemethods/hashy.rb +99 -97
  32. data/lib/striuct/instancemethods/lock.rb +46 -44
  33. data/lib/striuct/instancemethods/object.rb +50 -48
  34. data/lib/striuct/instancemethods/requirements.rb +9 -13
  35. data/lib/striuct/instancemethods/safety.rb +11 -9
  36. data/lib/striuct/instancemethods/setter.rb +46 -45
  37. data/lib/striuct/instancemethods/to_s.rb +39 -37
  38. data/lib/striuct/instancemethods/validation.rb +46 -29
  39. data/lib/striuct/instancemethods/values.rb +50 -48
  40. data/lib/striuct/singleton_class.rb +25 -18
  41. data/lib/striuct/structs.rb +3 -3
  42. data/lib/striuct.rb +7 -3
  43. metadata +18 -209
  44. data/.gitignore +0 -35
  45. data/.travis.yml +0 -17
  46. data/.yardopts +0 -1
  47. data/Gemfile +0 -11
  48. data/MIT-LICENSE +0 -22
  49. data/Rakefile +0 -11
  50. data/benchmark/basics.rb +0 -56
  51. data/example/README.rb +0 -50
  52. data/example/example1.rb +0 -195
  53. data/example/example2.rb +0 -20
  54. data/example/see_trace.rb +0 -32
  55. data/lib/striuct/instancemethods/keyvalidatable.rb +0 -9
  56. data/striuct.gemspec +0 -45
  57. data/test/helper.rb +0 -3
  58. data/test/test_sglc-constructor.rb +0 -36
  59. data/test/test_subc-c-add_members.rb +0 -13
  60. data/test/test_subc-c-close_member.rb +0 -36
  61. data/test/test_subc-c-constructor.rb +0 -92
  62. data/test/test_subc-c-copy.rb +0 -71
  63. data/test/test_subc-c-freeze.rb +0 -36
  64. data/test/test_subc-c-inheritable.rb +0 -58
  65. data/test/test_subc-c-safety_naming.rb +0 -73
  66. data/test/test_subc-f-alias_member.rb +0 -54
  67. data/test/test_subc-f-enum.rb +0 -159
  68. data/test/test_subc-f-predicate.rb +0 -647
  69. data/test/test_subc-f-to_struct.rb +0 -61
  70. data/test/test_subc-f-validation_util.rb +0 -59
  71. data/test/test_subc-f_debug.rb +0 -39
  72. data/test/test_subc-f_name.rb +0 -525
  73. data/test/test_subc-i-accessor.rb +0 -138
  74. data/test/test_subc-i-adjuster.rb +0 -95
  75. data/test/test_subc-i-assign.rb +0 -53
  76. data/test/test_subc-i-basic.rb +0 -43
  77. data/test/test_subc-i-cast.rb +0 -27
  78. data/test/test_subc-i-compare.rb +0 -52
  79. data/test/test_subc-i-copy.rb +0 -23
  80. data/test/test_subc-i-default_value.rb +0 -129
  81. data/test/test_subc-i-freeze.rb +0 -19
  82. data/test/test_subc-i-hashlike.rb +0 -144
  83. data/test/test_subc-i-keyvalidatable.rb +0 -25
  84. data/test/test_subc-i-lock.rb +0 -40
  85. data/test/test_subc-i-must.rb +0 -30
  86. data/test/test_subc-i-to_s_family.rb +0 -26
  87. data/test/test_subc-i-validation_specific_conditions.rb +0 -297
  88. data/test/test_subc-i-validation_with_getter.rb +0 -33
  89. data/test/test_version.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a5238390f14805baa497d1cd3acec45fc10faa233ce94af4782aa5570606b56
4
- data.tar.gz: e703ea310209502b772938d9eee312e26fcfdec30189c41e071107b125574ebb
3
+ metadata.gz: 1a14fe7f8c251b39c9e7a8d65fc96b62519a6e271eb5765b043f92cfe1b8bc3b
4
+ data.tar.gz: be0b9456cee901dc7d0079e5661de91cda71b52cdae47fa1277cd7b833310126
5
5
  SHA512:
6
- metadata.gz: 4650584be9988e6f8ed9b1a58cfa5912d099aed4377e035750ee158216fa8bc06c46c53386bc5b1188dd302847112c337d750ac1a103810bd83ab25ae5f920c4
7
- data.tar.gz: 3edc0199746228322c017bf8eefc619352a53882cf908d9e525392faaa43a5314ec37529ce97cfc7b40917d2dbca5da393cb5580b3d8c1ae673cdeea22efdf42
6
+ metadata.gz: a7600df197c958a8fc6f37cfec1f0bff19ec3c1542f469ed12f927193f060c8e1a4c211d6c0d3411d344e9562714b7c8cf159469409c4635d0018abd5c855bcd
7
+ data.tar.gz: 03b8604868221c485c16c99ce1e428da36f2c5f9db6c0458957f460f0a16aaba55753043cb65901df1f695fc5c9bf069d0b09dae9aa88f50081200844d3ca9c1
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2011 Kenichi Kamiya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,52 +1,40 @@
1
- striuct
2
- =======
1
+ # striuct
3
2
 
4
- [![Build Status](https://secure.travis-ci.org/kachick/striuct.png)](http://travis-ci.org/kachick/striuct)
3
+ ![Build Status](https://github.com/kachick/striuct/actions/workflows/test_behaviors.yml/badge.svg?branch=main)
5
4
  [![Gem Version](https://badge.fury.io/rb/striuct.png)](http://badge.fury.io/rb/striuct)
6
- [![Dependency Status](https://gemnasium.com/kachick/striuct.svg)](https://gemnasium.com/kachick/striuct)
7
-
8
- Description
9
- -----------
10
5
 
11
6
  Struct++
12
7
 
13
- Features
14
- --------
8
+ ## Usage
15
9
 
16
- ### Strict
10
+ Require Ruby 2.6 or later
17
11
 
18
- * Easy and Flexible Validations
19
- * Prevent to conflict member names
20
- * Lock setters for each member
12
+ Add this line to your `Gemfile`
21
13
 
22
- ### Useful
23
-
24
- * Hook just before setters
25
- * Default value
26
- * Member aliasing
27
- * Inheritable
28
- * Handling between nil <-> unassigned
29
- * More flendly API for Hash
14
+ ```ruby
15
+ gem 'striuct', '~> 0.9.0'
16
+ ```
30
17
 
31
- ### Onepoint
18
+ Then add below code into your Ruby code
32
19
 
33
- * Base API looks like Struct
34
- * Pure Ruby :)
20
+ ```ruby
21
+ require 'striuct'
22
+ ```
35
23
 
36
- Usage
37
- -----
24
+ ### Overview
38
25
 
39
- ### Overview - Case 1
26
+ #### Case 1
40
27
 
41
28
  ```ruby
42
29
  require 'striuct'
43
30
 
44
31
  class Person < Striuct
45
- member :fullname, AND(String, /\A.+\z/) # Flexible Validation
46
- alias_member :name, :fullname # Use other name
32
+ member :full_name, AND(String, /\A.+\z/) # Flexible Validation
33
+ alias_member :name, :full_name # Use other name
47
34
  end
48
35
 
49
- class User < Person # Inheritable
36
+ # Inheritable
37
+ class User < Person
50
38
  member :id, Integer, # Looks typed validation
51
39
  default_proc: ->{User.next_id} # With default value
52
40
 
@@ -57,13 +45,14 @@ class User < Person # Inheritable
57
45
  end
58
46
 
59
47
  john = User.new 'john'
60
- john[:name] #=> 'john'
48
+ john[:name] #=> 'john'
61
49
  john.name = '' #=> Exception # Validate with setter
62
50
  john.id #=> 1
63
51
  ken = User[name: 'ken'] # Construct from hash
64
52
  ken.id #=> 2
65
53
  ```
66
- ### Overview - Case 2
54
+
55
+ #### Case 2
67
56
 
68
57
  ```ruby
69
58
  class Foo < Striuct
@@ -75,7 +64,7 @@ end
75
64
 
76
65
  foo = Foo.new
77
66
 
78
- # nil <-> unaasigned
67
+ # nil <-> unassigned
79
68
  foo.foo #=> nil
80
69
  foo.assigned?(:foo) #=> false
81
70
  foo.foo = nil
@@ -93,7 +82,7 @@ foo.with_adjuster = '5'
93
82
  foo.with_adjuster #=> 5 # Casted via adjuster
94
83
  ```
95
84
 
96
- ### Overview - Case 3
85
+ #### Case 3
97
86
 
98
87
  ```ruby
99
88
  class UseMustOption < Striuct
@@ -103,37 +92,32 @@ end
103
92
  UseMustOption.new #=> InvalidOperationError "`foo` require a value under `must` option "
104
93
  ```
105
94
 
95
+ ## Features
106
96
 
107
- ### How to build flexible conditions ?
108
-
109
- * That from validation library.
110
- See the [validation-API](http://kachick.github.com/validation/yard/frames.html)
111
-
112
- Requirements
113
- -------------
97
+ ### Strict
114
98
 
115
- * Ruby - [2.2 or later](http://travis-ci.org/#!/kachick/striuct)
99
+ * Easy and Flexible Validations
100
+ * Basically use `#===` for the validation
101
+ * The pattern builder DSL is just using [eqq](https://github.com/kachick/eqq)
102
+ * When passed the Proc, it will be evaluated in the instance context
103
+ * Prevent to conflict member names
104
+ * Lock setters for each member
116
105
 
117
- Install
118
- -------
106
+ ### Useful
119
107
 
120
- ```bash
121
- gem install striuct
122
- ```
108
+ * Hook just before setters
109
+ * Default value
110
+ * Member aliasing
111
+ * Inheritable
112
+ * Handling between nil <-> unassigned
113
+ * Similar API for Hash
123
114
 
124
- Link
125
- ----
115
+ ### Finally
126
116
 
127
- * [Code](https://github.com/kachick/striuct)
128
- * [Wiki](https://github.com/kachick/striuct/wiki)
129
- * [API](http://www.rubydoc.info/github/kachick/striuct)
130
- * [Issues](https://github.com/kachick/striuct/issues)
131
- * [CI](http://travis-ci.org/#!/kachick/striuct)
132
- * [gem](https://rubygems.org/gems/striuct)
117
+ * Base API looks like Struct
118
+ * Pure Ruby :)
133
119
 
134
- License
135
- --------
120
+ ## Link
136
121
 
137
- The MIT X11 License
138
- Copyright (c) 2011 Kenichi Kamiya
139
- See MIT-LICENSE for further details.
122
+ * [Repository](https://github.com/kachick/striuct)
123
+ * [API documents](https://kachick.github.io/striuct/)
@@ -1,5 +1,9 @@
1
- require 'validation'
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'eqq'
5
+
2
6
  require_relative 'structs'
3
7
  require_relative 'classmethods/requirements'
4
8
  require_relative 'instancemethods/requirements'
5
- require_relative 'singleton_class'
9
+ require_relative 'singleton_class'
@@ -1,10 +1,10 @@
1
1
  Note
2
2
  =====
3
3
 
4
- This dir's tree is diveded under roles/features.
4
+ This dir's tree is divided under roles/features.
5
5
  Not only divided by CONSTANT names.
6
6
 
7
7
  CONSTANT
8
8
  --------
9
9
 
10
- * attributes - Attributes
10
+ * attributes - Attributes
@@ -1,15 +1,79 @@
1
- class Striuct; module ClassMethods
2
-
3
- # @group Adjuster
4
-
5
- # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
6
- def adjuster_for(key)
7
- autonym = autonym_for_key key
8
- raise KeyError unless with_adjuster? autonym
9
-
10
- _attributes_for(autonym).adjuster
11
- end
1
+ # frozen_string_literal: true
2
+
3
+ class Striuct
4
+ module ClassMethods
5
+ # @group Adjuster
6
+
7
+ # Adjuster Builders
8
+ # Apply adjuster when passed pattern.
9
+ # @param pattern [Proc, Method, #===]
10
+ # @param adjuster [Proc, #to_proc]
11
+ # @return [Proc]
12
+ def WHEN(pattern, adjuster)
13
+ unless Eqq.pattern?(pattern)
14
+ raise ArgumentError, 'wrong object for pattern'
15
+ end
16
+
17
+ unless Striuct.adjustable?(adjuster)
18
+ raise ArgumentError, 'wrong object for adjuster'
19
+ end
20
+
21
+ ->v { _valid?(pattern, v) ? adjuster.call(v) : v }
22
+ end
23
+
24
+ # Sequential apply all adjusters.
25
+ # @param adjuster1 [Proc, #to_proc]
26
+ # @param adjuster2 [Proc, #to_proc]
27
+ # @param adjusters [Proc, #to_proc]
28
+ # @return [Proc]
29
+ def INJECT(adjuster1, adjuster2, *adjusters)
30
+ adjusters = [adjuster1, adjuster2, *adjusters]
12
31
 
13
- # @endgroup
32
+ unless adjusters.all? { |f| adjustable?(f) }
33
+ raise ArgumentError, 'wrong object for adjuster'
34
+ end
14
35
 
15
- end; end
36
+ ->v {
37
+ adjusters.reduce(v) { |ret, adjuster| adjuster.call(ret) }
38
+ }
39
+ end
40
+
41
+ # Accept any parser when that respond to parse method.
42
+ # @param parser [#parse]
43
+ # @return [Proc]
44
+ def PARSE(parser)
45
+ if !::Integer.equal?(parser) && !parser.respond_to?(:parse)
46
+ raise ArgumentError, 'wrong object for parser'
47
+ end
48
+
49
+ ->v {
50
+ if ::Integer.equal?(parser)
51
+ ::Kernel.Integer(v)
52
+ else
53
+ parser.parse(
54
+ case v
55
+ when String
56
+ v
57
+ when ->_ { v.respond_to?(:to_str) }
58
+ v.to_str
59
+ when ->_ { v.respond_to?(:read) }
60
+ v.read
61
+ else
62
+ raise TypeError, 'wrong object for parsing source'
63
+ end
64
+ )
65
+ end
66
+ }
67
+ end
68
+
69
+ # @param [Symbol, String, #to_sym, Integer, #to_int] key - name / index
70
+ def adjuster_for(key)
71
+ autonym = autonym_for_key(key)
72
+ raise KeyError unless with_adjuster?(autonym)
73
+
74
+ _attributes_for(autonym).adjuster
75
+ end
76
+
77
+ # @endgroup
78
+ end
79
+ end
@@ -1,114 +1,116 @@
1
- class Striuct; module ClassMethods
2
-
3
- # Attributes for autonym of each member
4
- class Attributes
5
-
6
- VALUES = [ :condition,
7
- :adjuster ].freeze
8
-
9
- BOOLEANS = [
10
- :must,
11
- :safety_setter,
12
- :safety_getter
13
- ].freeze
14
-
15
- def initialize
16
- @hash = {
17
- must: false,
18
- safety_setter: false,
19
- safety_getter: false
20
- }
21
- end
22
-
23
- VALUES.each do |role|
24
- define_method :"with_#{role}?" do
25
- @hash.has_key? role
1
+ # frozen_string_literal: true
2
+
3
+ class Striuct
4
+ module ClassMethods
5
+ # Attributes for autonym of each member
6
+ class Attributes
7
+ VALUES = [:condition,
8
+ :adjuster].freeze
9
+
10
+ BOOLEANS = [
11
+ :must,
12
+ :safety_setter,
13
+ :safety_getter
14
+ ].freeze
15
+
16
+ def initialize
17
+ @hash = {
18
+ must: false,
19
+ safety_setter: false,
20
+ safety_getter: false
21
+ }
26
22
  end
27
-
28
- define_method role do
29
- @hash.fetch role
23
+
24
+ VALUES.each do |role|
25
+ define_method :"with_#{role}?" do
26
+ @hash.key?(role)
27
+ end
28
+
29
+ define_method role do
30
+ @hash.fetch(role)
31
+ end
30
32
  end
31
- end
32
33
 
33
- def condition=(condition)
34
- unless ::Validation.conditionable? condition
35
- raise TypeError, 'wrong object for condition'
34
+ def condition=(condition)
35
+ unless Eqq.pattern?(condition)
36
+ raise TypeError, 'wrong object for condition'
37
+ end
38
+
39
+ @hash[:condition] = condition
36
40
  end
37
41
 
38
- @hash[:condition] = condition
39
- end
42
+ def adjuster=(adjuster)
43
+ unless Striuct.adjustable?(adjuster)
44
+ raise ArgumentError, 'wrong object for adjuster'
45
+ end
40
46
 
41
- def adjuster=(adjuster)
42
- unless ::Validation.adjustable? adjuster
43
- raise ArgumentError, 'wrong object for adjuster'
47
+ @hash[:adjuster] = adjuster
44
48
  end
45
49
 
46
- @hash[:adjuster] = adjuster
47
- end
50
+ BOOLEANS.each do |role|
51
+ define_method :"with_#{role}?" do
52
+ @hash.fetch(role)
53
+ end
54
+
55
+ define_method :"#{role}=" do |arg|
56
+ raise TypeError unless arg.equal?(true) || arg.equal?(false)
48
57
 
49
- BOOLEANS.each do |role|
50
- define_method :"with_#{role}?" do
51
- @hash.fetch role
58
+ @hash[role] = arg
59
+ end
52
60
  end
53
-
54
- define_method :"#{role}=" do |arg|
55
- raise TypeError unless arg.equal?(true) or arg.equal?(false)
56
61
 
57
- @hash[role] = arg
58
- end
59
- end
62
+ def with_default?
63
+ @hash.key?(:default_value)
64
+ end
60
65
 
61
- def with_default?
62
- @hash.has_key? :default_value
63
- end
66
+ def default_value
67
+ @hash.fetch(:default_value)
68
+ end
64
69
 
65
- def default_value
66
- @hash.fetch :default_value
67
- end
70
+ def default_type
71
+ @hash.fetch(:default_type)
72
+ end
68
73
 
69
- def default_type
70
- @hash.fetch :default_type
71
- end
74
+ # @param [Symbol] type - :value / :lazy
75
+ def set_default(value, type)
76
+ raise TypeError unless type.equal?(:value) || type.equal?(:lazy)
72
77
 
73
- # @param [Symbol] type - :value / :lazy
74
- def set_default(value, type)
75
- raise TypeError unless type.equal?(:value) or type.equal?(:lazy)
76
- check_default_lazy_proc value if type.equal?(:lazy)
77
-
78
- @hash[:default_type] = type
79
- @hash[:default_value] = value
80
- end
78
+ check_default_lazy_proc(value) if type.equal?(:lazy)
81
79
 
82
- def check_default_lazy_proc(_proc)
83
- raise TypeError unless _proc.respond_to? :call
84
- arity = _proc.arity
85
- unless arity <= 2
86
- raise ArgumentError, "wrong number of block parameter #{arity} for 0..2"
80
+ @hash[:default_type] = type
81
+ @hash[:default_value] = value
87
82
  end
88
- end
89
83
 
90
- def freeze
91
- ret = super
92
- @hash.freeze
93
- ret
94
- end
84
+ def check_default_lazy_proc(proc)
85
+ raise TypeError unless proc.respond_to?(:call)
95
86
 
96
- def dup
97
- ret = super
98
- @hash = @hash.dup
99
- ret
100
- end
101
-
102
- private
103
-
104
- def initialize_copy(original)
105
- ret = super original
106
- @hash = @hash.dup
107
- ret
108
- end
87
+ arity = proc.arity
88
+ unless arity <= 2
89
+ raise ArgumentError, "wrong number of block parameter #{arity} for 0..2"
90
+ end
91
+ end
109
92
 
110
- end
93
+ def freeze
94
+ ret = super
95
+ @hash.freeze
96
+ ret
97
+ end
98
+
99
+ def dup
100
+ ret = super
101
+ @hash = @hash.dup
102
+ ret
103
+ end
111
104
 
112
- private_constant :Attributes
105
+ private
113
106
 
114
- end; end
107
+ def initialize_copy(original)
108
+ ret = super(original)
109
+ @hash = @hash.dup
110
+ ret
111
+ end
112
+ end
113
+
114
+ private_constant :Attributes
115
+ end
116
+ end