accessory 0.1.2 → 0.1.7

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.
@@ -0,0 +1,28 @@
1
+ module Accessory; end
2
+ module Accessory::TraversalPosition; end
3
+
4
+ ##
5
+ # Represents an element encountered during +#each+ traversal of an +Enumerable+.
6
+
7
+ class Accessory::TraversalPosition::EnumerableAtOffset
8
+ ##
9
+ # @!visibility private
10
+ def initialize(offset, elem_at, is_first: false, is_last: false)
11
+ @offset = offset
12
+ @elem_at = elem_at
13
+ @is_first = is_first
14
+ @is_last = is_last
15
+ end
16
+
17
+ # @return [Integer] the offset of +elem_at+ in the Enumerable
18
+ attr_reader :offset
19
+
20
+ # @return [Object] the element under the cursor, if applicable
21
+ attr_reader :elem_at
22
+
23
+ # @return [Boolean] true when {#elem_at} is the first element of the +Enumerable+
24
+ def first?; @is_first; end
25
+
26
+ # @return [Boolean] true when {#elem_at} is the last element of the +Enumerable+
27
+ def last?; @is_last; end
28
+ end
@@ -0,0 +1,55 @@
1
+ module Accessory; end
2
+ module Accessory::TraversalPosition; end
3
+
4
+ ##
5
+ # Represents the empty intervals between and surrounding the elements of an
6
+ # +Enumerable#each+ traversal.
7
+ #
8
+ # Examples to build intuition:
9
+ #
10
+ # * An +EnumerableBeforeOffset+ with an <tt>.offset</tt> of <tt>0</tt>
11
+ # represents the position directly before the first result from
12
+ # <tt>#each</tt>, i.e. "the beginning." Using {Lens#put_in} at this position
13
+ # will _prepend_ to the +Enumerable+.
14
+ #
15
+ # * An +EnumerableBeforeOffset+ with an <tt>.offset</tt> equal to the
16
+ # <tt>#length</tt> of the +Enumerable+ (recognizable by
17
+ # <tt>EnumerableBeforeOffset#last?</tt> returning +true+) represents
18
+ # represents the position directly before the end of the enumeration,
19
+ # i.e. "the end" of the +Enumerable+. Using {Lens#put_in} at this position
20
+ # will _append_ to the +Enumerable+.
21
+ #
22
+ # * In general, using {Lens#put_in} with an +EnumerableBeforeOffset+ with an
23
+ # <tt>.offset</tt> of +n+ will insert an element _between_ elements
24
+ # <tt>n - 1</tt> and +n+ in the enumeration sequence.
25
+ #
26
+ # * Returning <tt>:pop</tt> from {Lens#get_and_update_in} for an
27
+ # +EnumerableBeforeOffset+-terminated {Lens} will have no effect, as
28
+ # you're removing an empty slice.
29
+
30
+ class Accessory::TraversalPosition::EnumerableBeforeOffset
31
+ ##
32
+ # @!visibility private
33
+ def initialize(offset, elem_before, elem_after, is_first: false, is_last: false)
34
+ @offset = offset
35
+ @elem_before = elem_before
36
+ @elem_after = elem_after
37
+ @is_first = is_first
38
+ @is_last = is_last
39
+ end
40
+
41
+ # @return [Integer] the offset of +elem_after+ in the Enumerable
42
+ attr_reader :offset
43
+
44
+ # @return [Object] the element before the cursor, if applicable
45
+ attr_reader :elem_before
46
+
47
+ # @return [Object] the element after the cursor, if applicable
48
+ attr_reader :elem_after
49
+
50
+ # @return [Boolean] true when {#elem_after} is the first element of the +Enumerable+
51
+ def first?; @is_first; end
52
+
53
+ # @return [Boolean] true when {#elem_before} is the last element of the +Enumerable+
54
+ def last?; @is_last; end
55
+ end
@@ -1,3 +1,3 @@
1
1
  module Accessory
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.7"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accessory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Levi Aul
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-11 00:00:00.000000000 Z
11
+ date: 2021-01-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -29,9 +29,10 @@ files:
29
29
  - lib/accessory/accessors/instance_variable_accessor.rb
30
30
  - lib/accessory/accessors/last_accessor.rb
31
31
  - lib/accessory/accessors/subscript_accessor.rb
32
- - lib/accessory/array_cursor_position.rb
32
+ - lib/accessory/bound_lens.rb
33
33
  - lib/accessory/lens.rb
34
- - lib/accessory/lens_path.rb
34
+ - lib/accessory/traversal_position/enumerable_at_offset.rb
35
+ - lib/accessory/traversal_position/enumerable_before_offset.rb
35
36
  - lib/accessory/version.rb
36
37
  homepage: https://github.com/tsutsu/accessory
37
38
  licenses:
@@ -1,18 +0,0 @@
1
- module Accessory; end
2
-
3
- class Accessory::ArrayCursorPosition
4
- def initialize(offset, elem_before, elem_after, is_first: false, is_last: false)
5
- @offset = offset
6
- @elem_before = elem_before
7
- @elem_after = elem_after
8
- @is_first = is_first
9
- @is_last = is_last
10
- end
11
-
12
- attr_reader :offset
13
- attr_reader :elem_before
14
- attr_reader :elem_after
15
-
16
- def first?; @is_first; end
17
- def last?; @is_last; end
18
- end
@@ -1,150 +0,0 @@
1
- module Accessory; end
2
-
3
- require 'accessory/accessor'
4
- require 'accessory/accessors/subscript_accessor'
5
-
6
- class Accessory::LensPath
7
- def self.empty
8
- @empty_lens_path ||= (new([]).freeze)
9
- end
10
-
11
- def self.[](*path)
12
- new(path).freeze
13
- end
14
-
15
- class << self
16
- private :new
17
- end
18
-
19
- def initialize(initial_parts)
20
- @parts = []
21
-
22
- for part in initial_parts
23
- append_accessor!(part)
24
- end
25
- end
26
-
27
- def to_a
28
- @parts
29
- end
30
-
31
- def inspect(format: :long)
32
- parts_desc = @parts.map{ |part| part.inspect(format: :short) }.join(', ')
33
- parts_desc = "[#{parts_desc}]"
34
-
35
- case format
36
- when :long
37
- "#LensPath#{parts_desc}"
38
- when :short
39
- parts_desc
40
- end
41
- end
42
-
43
- def then(accessor)
44
- d = self.dup
45
- d.append_accessor!(accessor)
46
- d.freeze
47
- end
48
-
49
- def dup
50
- d = super
51
- d.instance_eval do
52
- @parts = @parts.dup
53
- end
54
- d
55
- end
56
-
57
- def +(lp_b)
58
- parts =
59
- case lp_b
60
- when Accessory::LensPath
61
- lp_b.to_a
62
- when Array
63
- lp_b
64
- else
65
- [lp_b]
66
- end
67
-
68
- d = self.dup
69
- for part in parts
70
- d.append_accessor!(part)
71
- end
72
- d.freeze
73
- end
74
-
75
- alias_method :/, :+
76
-
77
- def append_accessor!(part)
78
- accessor =
79
- case part
80
- when Accessory::Accessor
81
- part
82
- when Array
83
- Accessory::SubscriptAccessor.new(part[0], default: part[1])
84
- else
85
- Accessory::SubscriptAccessor.new(part)
86
- end
87
-
88
- unless @parts.empty?
89
- @parts.last.make_default_fn = accessor.default_fn_for_previous_step
90
- end
91
-
92
- @parts.push(accessor)
93
- end
94
-
95
- protected :append_accessor!
96
-
97
- def get_in(doc)
98
- if @parts.empty?
99
- doc
100
- else
101
- get_in_step(doc, @parts)
102
- end
103
- end
104
-
105
- def get_and_update_in(doc, &mutator_fn)
106
- if @parts.empty?
107
- doc
108
- else
109
- get_and_update_in_step(doc, @parts, mutator_fn)
110
- end
111
- end
112
-
113
- def update_in(data, &new_value_fn)
114
- _, new_data = self.get_and_update_in(data){ |v| [nil, new_value_fn.call(v)] }
115
- new_data
116
- end
117
-
118
- def put_in(data, new_value)
119
- _, new_data = self.get_and_update_in(data){ [nil, new_value] }
120
- new_data
121
- end
122
-
123
- def pop_in(data)
124
- self.get_and_update_in(data){ :pop }
125
- end
126
-
127
- private
128
- def get_in_step(data, path)
129
- step_accessor = path.first
130
- rest_of_path = path[1..-1]
131
-
132
- if rest_of_path.empty?
133
- step_accessor.get(data)
134
- else
135
- step_accessor.get(data){ |v| get_in_step(v, rest_of_path) }
136
- end
137
- end
138
-
139
- private
140
- def get_and_update_in_step(data, path, mutator_fn)
141
- step_accessor = path.first
142
- rest_of_path = path[1..-1]
143
-
144
- if rest_of_path.empty?
145
- step_accessor.get_and_update(data, &mutator_fn)
146
- else
147
- step_accessor.get_and_update(data){ |v| get_and_update_in_step(v, rest_of_path, mutator_fn) }
148
- end
149
- end
150
- end