recurring_date 0.0.3 → 0.1.1

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
- SHA1:
3
- metadata.gz: d4cc8eff5210dd36470912daacacd4a4a44f7109
4
- data.tar.gz: d339946cc56e30491139b5577a63033e963be901
2
+ SHA256:
3
+ metadata.gz: 7852f2274c200712705a14f593a92ad3b68d69a935b4dd81d4d6ee29b3b83035
4
+ data.tar.gz: 20f777337f3cb1afde4cdc3fc03f95833a70b1816116f486f4887e2724fda14e
5
5
  SHA512:
6
- metadata.gz: 4465192a86991d9f4cd3fb2d0d9eede1845ddc690cc39a2c9990d7dd0947c6935fdc2ea4d417e3856a399e15fa327514168f3813a5303aa92a99e11bb168f029
7
- data.tar.gz: 31e51294b9b93401ae693aee6d2c61b01ebb25947835f5bd41d6e86bff79cf608dd69a9eba680de394e955459c4431152e788a5c8427a0fdb4d253381184f4e2
6
+ metadata.gz: 13b085b3ccd9bff2227f451979adadf7be355ca0da35d09a15827848217d0e59d3bdd150447e597866a63f42ddbd68a59fb55ae8b50b17e22cc589c1eb738eba
7
+ data.tar.gz: 9744b7f105c3aa9099210208bd4ee5447c9b91fc2aea3d3919e390f628cbbf4012f16f5841ee52f5da533b8a1e3c4f7df44c4a2e2fcc07f8b41445da8e5b8070
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /spec/reports/
3
+ /tmp/
4
+
5
+ # rspec failure tracking
6
+ .rspec_status
7
+
8
+ # ignore gem releses
9
+ *.gem
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,31 @@
1
+ image: "reg01.binarapps.com/docker-images/ruby-rvm:2.3.1"
2
+
3
+ variables:
4
+
5
+ cache:
6
+ key: "$CI_BUILD_REF_NAME"
7
+
8
+ stages:
9
+ - build
10
+ - test
11
+
12
+ before_script:
13
+ - rvm current
14
+ - bundle install --jobs $(nproc) --path /cache
15
+
16
+ bundle install:
17
+ stage: build
18
+ before_script: []
19
+ script:
20
+ - rvm current
21
+ - bundle install --jobs $(nproc) --path /cache
22
+
23
+ rspec:
24
+ stage: test
25
+ script:
26
+ - bundle exec rspec -fp
27
+
28
+ rubocop:
29
+ stage: test
30
+ script:
31
+ - bundle exec rubocop
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,39 @@
1
+ AllCops:
2
+ Include:
3
+ - '**/Gemfile'
4
+ Exclude:
5
+ - '**/Gemfile*'
6
+ - '**/*.gemspec'
7
+ TargetRubyVersion: 2.3
8
+ Style/WhileUntilModifier:
9
+ MaxLineLength: 120
10
+ Style/WhileUntilModifier:
11
+ MaxLineLength: 120
12
+ Metrics/LineLength:
13
+ Max: 120
14
+ Metrics/MethodLength:
15
+ Max: 25
16
+ Metrics/AbcSize:
17
+ Max: 50
18
+ Metrics/ClassLength:
19
+ Enabled: false
20
+ Metrics/BlockLength:
21
+ Enabled: false
22
+ Style/Documentation:
23
+ Enabled: false
24
+ Style/AlignParameters:
25
+ EnforcedStyle: with_fixed_indentation
26
+ Style/MultilineMethodCallIndentation:
27
+ EnforcedStyle: indented
28
+ Style/DotPosition:
29
+ EnforcedStyle: trailing
30
+ Style/MultilineHashBraceLayout:
31
+ Enabled: false
32
+ Style/Lambda:
33
+ Enabled: false
34
+ Style/CharacterLiteral:
35
+ Enabled: false
36
+ Style/CharacterLiteral:
37
+ Enabled: false
38
+ Style/FrozenStringLiteralComment:
39
+ Enabled: false
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ recurring_date
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.5
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ recurring_date (0.1.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (10.5.0)
11
+ rspec (3.5.0)
12
+ rspec-core (~> 3.5.0)
13
+ rspec-expectations (~> 3.5.0)
14
+ rspec-mocks (~> 3.5.0)
15
+ rspec-core (3.5.4)
16
+ rspec-support (~> 3.5.0)
17
+ rspec-expectations (3.5.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.5.0)
20
+ rspec-mocks (3.5.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.5.0)
23
+ rspec-support (3.5.0)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.17)
30
+ rake (~> 10.0)
31
+ recurring_date!
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 1.17.3
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Paweł Placzyński
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 ADDED
@@ -0,0 +1,92 @@
1
+ # recurring_date
2
+
3
+ Iterate over a set of dates, giving an iteration conditions.
4
+
5
+ This gem provides an enumerator `RecurringDate::Enumerator`, selecting specific dates due to the recursion pattern.
6
+
7
+ `RecurringDate::Enumerator` is lazy so pattern can be applied to an infinite set of dates.
8
+
9
+ The enumerator operates on objects that implements the `Enumerator#each` and yields `Date`.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'recurring_date'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install recurring_date
26
+
27
+ ## Usage
28
+
29
+
30
+ ### `RecurringDate`
31
+
32
+ `RecurringDate` module adds two methods to class `Date`:
33
+
34
+ | Method | Description
35
+ |------------|-------------
36
+ | `#mweek` | Returns a number - n'th occurence of the week day in the month.
37
+ | `#to_enum` | Returns `RecurringDate::Enumerator` enumerator with given range from `self` iterating forever (infinite set).
38
+
39
+ ### `RecurringDate::Enumerator`
40
+
41
+ The enumerator implements bunch of chainable methods to provide simple DSL for selecting wanted recursion pattern.
42
+
43
+ | Pattern | DSL
44
+ |----------------------------------------------------------|-----
45
+ | dates matching `condition` | `enumerator.select { ❘d❘ condition }`
46
+ | dates not matching `condition` | `enumerator.reject { ❘d❘ condition }`
47
+ | dates matching `condition` (with index `i`) | `enumerator.select_with_index { ❘d, i❘ condition }`
48
+ | dates from beginning as long as `condition` is fulfilled | `enumerator.take_while { ❘d❘ condition }`
49
+ | `n` dates from beginning | `enumerator.take(n)`
50
+ | every 4th of October | `enumerator.month(10).mday(4)`
51
+ | every 3rd and 23rd of August | `enumerator.month(8).mday(3, 23)`
52
+ | every 17th June and July | `enumerator.month(6, 7).mday(17)`
53
+ | every 10th and 12th of February and April | `enumerator.month(2, 4).mday(10, 12)`
54
+ | every 13th of the month | `enumerator.mday(13)`
55
+ | every 21st and 23rd of the month | `enumerator.mday(21, 23)`
56
+ | every Friday | `enumerator.wday(5)`
57
+ | every Saturday and Sunday | `enumerator.wday(6, 0)`
58
+ | every Saturday and Sunday | `enumerator.matching(6, 0) { ❘d❘ d.wday }`
59
+ | every Saturday and Sunday | `enumerator.matching(6, 0, &:wday)`
60
+ | every 4th day | `enumerator.pattern(4)`
61
+ | every 7th or 10th day | `enumerator.pattern(7, 10)`
62
+ | every second Friday | `enumerator.wday(5).pattern(2)`
63
+ | every 2nd Monday of the month | `enumerator.wday(1).mweek(2)`
64
+ | 2nd and 4th Sunday of the month | `enumerator.wday(0).mweek(2,4)`
65
+ | 3rd Tuesday and Wednesday of the month | `enumerator.wday(2,3).mweek(3)`
66
+ | until `date` | `enumerator.until(date)`
67
+
68
+ ###### NOTE
69
+
70
+ * There is a method `RecurringDate::Enumerator.eternity` that returns `RecurringDate::Enumerator` instance that iterates perpetualy over every day after _1970-01-01_.
71
+ * The `RecurringDate::Enumerator.from(date)` method does the same, but from `date`.
72
+ * Every enumerator method (except `select`, `select_with_index`, `reject`, `take`, `take_while` and `until`) has a corresponding method with `not_` prefix.
73
+ * For `rails` models the pattern can be used to select records, like: `Model.where('column::date IN (?)', dates)`.
74
+
75
+ ### Example
76
+
77
+ require 'recurring_date'
78
+ rule = RecurringDate::Enumerator.eternity
79
+ rule.wday(5).mweek(1) # => enumerator of all first Fridays of a month
80
+ rule.pattern(2).until(Date.new(2020, 8, 1)) # => enumerator of every second day until 2020-08-01
81
+ rule.wday(6,0).mweek(2,4).take(8) # => enumerator of next four 2nd and 4th weekends of a month
82
+ rule.to_a # => array of `Date` instances (be careful - it can be infinite)
83
+
84
+ ## Development
85
+
86
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
87
+
88
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `lib/recurring_date/version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
89
+
90
+ ## Contributing
91
+
92
+ Bug reports and pull requests are welcome on GitHub at https://github.com/placek/recurring_date.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'recurring_date'
5
+
6
+ require 'irb'
7
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
@@ -0,0 +1,132 @@
1
+ require 'date'
2
+
3
+ module RecurringDate
4
+ class Enumerator < ::Enumerator
5
+ def initialize(range)
6
+ super() do |result|
7
+ begin
8
+ range.each { |val| block_given? ? yield(result, val) : result << val }
9
+ rescue ::StopIteration
10
+ nil
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.eternity
16
+ from(Date.new(1970))
17
+ end
18
+
19
+ def self.from(date)
20
+ RecurringDate::Enumerator.new(infinity(date))
21
+ end
22
+
23
+ def yday(*args)
24
+ matching(*args, &:yday)
25
+ end
26
+
27
+ def mday(*args)
28
+ matching(*args, &:mday)
29
+ end
30
+
31
+ def wday(*args)
32
+ matching(*args, &:wday)
33
+ end
34
+
35
+ def mweek(*args)
36
+ matching(*args, &:mweek)
37
+ end
38
+
39
+ def month(*args)
40
+ matching(*args, &:month)
41
+ end
42
+
43
+ def year(*args)
44
+ matching(*args, &:year)
45
+ end
46
+
47
+ def not_yday(*args)
48
+ not_matching(*args, &:yday)
49
+ end
50
+
51
+ def not_mday(*args)
52
+ not_matching(*args, &:mday)
53
+ end
54
+
55
+ def not_wday(*args)
56
+ not_matching(*args, &:wday)
57
+ end
58
+
59
+ def not_mweek(*args)
60
+ not_matching(*args, &:mweek)
61
+ end
62
+
63
+ def not_month(*args)
64
+ not_matching(*args, &:month)
65
+ end
66
+
67
+ def not_year(*args)
68
+ not_matching(*args, &:year)
69
+ end
70
+
71
+ def matching(*args)
72
+ select { |date| args.include?(yield(date)) }
73
+ end
74
+
75
+ def not_matching(*args)
76
+ reject { |date| args.include?(yield(date)) }
77
+ end
78
+
79
+ def pattern(*args)
80
+ select_with_index do |_, i|
81
+ args.any? { |arg| ((i + 1) % arg).zero? }
82
+ end
83
+ end
84
+
85
+ def until(arg)
86
+ take_while { |date| date <= arg.to_date }
87
+ end
88
+
89
+ def select_with_index
90
+ index = 0
91
+ RecurringDate::Enumerator.new(self) do |result, value|
92
+ result << value if yield(value, index)
93
+ index += 1
94
+ end
95
+ end
96
+
97
+ def select
98
+ RecurringDate::Enumerator.new(self) { |result, value| result << value if yield(value) }
99
+ end
100
+
101
+ def reject
102
+ RecurringDate::Enumerator.new(self) { |result, value| result << value unless yield(value) }
103
+ end
104
+
105
+ def take(n)
106
+ taken = n
107
+ RecurringDate::Enumerator.new(self) do |result, value|
108
+ raise ::StopIteration if taken.zero?
109
+ result << value
110
+ taken -= 1
111
+ end
112
+ end
113
+
114
+ def take_while
115
+ RecurringDate::Enumerator.new(self) do |result, value|
116
+ raise ::StopIteration unless yield(value)
117
+ result << value
118
+ end
119
+ end
120
+
121
+ def inspect
122
+ ['#<RecurringDate::Enumerator:0x', object_id, '>'].join
123
+ end
124
+
125
+ def self.infinity(date)
126
+ ::Enumerator.new do |y|
127
+ i = date.prev_day
128
+ loop { y << (i = i.next) }
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,3 @@
1
+ module RecurringDate
2
+ VERSION = '0.1.1'.freeze
3
+ end
@@ -1,4 +1,4 @@
1
- require_relative 'recurring_date_enumerator'
1
+ require 'recurring_date/enumerator'
2
2
 
3
3
  module RecurringDate
4
4
  def mweek
@@ -6,7 +6,7 @@ module RecurringDate
6
6
  end
7
7
 
8
8
  def to_enum
9
- RecurringDateEnumerator.eternity(from: self)
9
+ RecurringDate::Enumerator.from(self)
10
10
  end
11
11
  end
12
12
 
@@ -0,0 +1,31 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'recurring_date/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'recurring_date'
7
+ spec.version = RecurringDate::VERSION
8
+ spec.authors = ['Paweł Placzyński']
9
+ spec.email = ['placzynski.pawel@gmail.com']
10
+
11
+ spec.summary = %q{Dates enumerator with conditions}
12
+ spec.description = %q{Iterate over a set of dates, giving an iteration conditions.}
13
+ spec.homepage = 'https://gitlab.binarapps.com/placek/recurring_date'
14
+
15
+ if spec.respond_to?(:metadata)
16
+ spec.metadata['homepage_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = 'https://gitlab.binarapps.com/placek/recurring_date'
18
+ else
19
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
20
+ end
21
+
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+
26
+ spec.require_paths = ['lib']
27
+
28
+ spec.add_development_dependency 'bundler', '~> 1.17'
29
+ spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'rspec', '~> 3.0'
31
+ end
metadata CHANGED
@@ -1,31 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recurring_date
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
- - Paweł Placzyński
7
+ - Paweł Placzyński
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-01 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Enumerator for recurring dates with specific patterns
11
+ date: 2020-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Iterate over a set of dates, giving an iteration conditions.
14
56
  email:
15
- - should@not-fail.pl
16
- - p.placzynski@binarapps.com
17
57
  - placzynski.pawel@gmail.com
18
- - silquenarmo@gmail.com
19
58
  executables: []
20
59
  extensions: []
21
60
  extra_rdoc_files: []
22
61
  files:
62
+ - ".gitignore"
63
+ - ".gitlab-ci.yml"
64
+ - ".rspec"
65
+ - ".rubocop.yml"
66
+ - ".ruby-gemset"
67
+ - ".ruby-version"
68
+ - Gemfile
69
+ - Gemfile.lock
70
+ - LICENSE
71
+ - README.md
72
+ - Rakefile
73
+ - bin/console
74
+ - bin/setup
23
75
  - lib/recurring_date.rb
24
- - lib/recurring_date_enumerator.rb
25
- homepage: ''
26
- licenses:
27
- - MIT
28
- metadata: {}
76
+ - lib/recurring_date/enumerator.rb
77
+ - lib/recurring_date/version.rb
78
+ - recurring_date.gemspec
79
+ homepage: https://gitlab.binarapps.com/placek/recurring_date
80
+ licenses: []
81
+ metadata:
82
+ homepage_uri: https://gitlab.binarapps.com/placek/recurring_date
83
+ source_code_uri: https://gitlab.binarapps.com/placek/recurring_date
29
84
  post_install_message:
30
85
  rdoc_options: []
31
86
  require_paths:
@@ -41,9 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
96
  - !ruby/object:Gem::Version
42
97
  version: '0'
43
98
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.6.11
99
+ rubygems_version: 3.0.6
46
100
  signing_key:
47
101
  specification_version: 4
48
- summary: Recurring dates enumerator
102
+ summary: Dates enumerator with conditions
49
103
  test_files: []
@@ -1,128 +0,0 @@
1
- require 'date'
2
-
3
- class RecurringDateEnumerator < Enumerator
4
- def initialize(range)
5
- super() do |result|
6
- begin
7
- range.each { |val| block_given? ? yield(result, val) : result << val }
8
- rescue StopIteration
9
- nil
10
- end
11
- end
12
- end
13
-
14
- def self.eternity(from: Date.new(1970))
15
- RecurringDateEnumerator.new(infinity(from))
16
- end
17
-
18
- def yday(*args)
19
- matching(*args, &:yday)
20
- end
21
-
22
- def mday(*args)
23
- matching(*args, &:mday)
24
- end
25
-
26
- def wday(*args)
27
- matching(*args, &:wday)
28
- end
29
-
30
- def mweek(*args)
31
- matching(*args, &:mweek)
32
- end
33
-
34
- def month(*args)
35
- matching(*args, &:month)
36
- end
37
-
38
- def year(*args)
39
- matching(*args, &:year)
40
- end
41
-
42
- def not_yday(*args)
43
- not_matching(*args, &:yday)
44
- end
45
-
46
- def not_mday(*args)
47
- not_matching(*args, &:mday)
48
- end
49
-
50
- def not_wday(*args)
51
- not_matching(*args, &:wday)
52
- end
53
-
54
- def not_mweek(*args)
55
- not_matching(*args, &:mweek)
56
- end
57
-
58
- def not_month(*args)
59
- not_matching(*args, &:month)
60
- end
61
-
62
- def not_year(*args)
63
- not_matching(*args, &:year)
64
- end
65
-
66
- def matching(*args)
67
- select { |date| args.include?(yield(date)) }
68
- end
69
-
70
- def not_matching(*args)
71
- reject { |date| args.include?(yield(date)) }
72
- end
73
-
74
- def pattern(*args)
75
- select_with_index do |_, i|
76
- args.any? do |arg|
77
- ((i + 1) % arg).zero?
78
- end
79
- end
80
- end
81
-
82
- def until(arg)
83
- take_while { |date| date <= arg.to_date }
84
- end
85
-
86
- def select_with_index
87
- index = 0
88
- RecurringDateEnumerator.new(self) do |result, value|
89
- result << value if yield(value, index)
90
- index += 1
91
- end
92
- end
93
-
94
- def select
95
- RecurringDateEnumerator.new(self) { |result, value| result << value if yield(value) }
96
- end
97
-
98
- def reject
99
- RecurringDateEnumerator.new(self) { |result, value| result << value unless yield(value) }
100
- end
101
-
102
- def take(n)
103
- taken = n
104
- RecurringDateEnumerator.new(self) do |result, value|
105
- raise StopIteration if taken.zero?
106
- result << value
107
- taken -= 1
108
- end
109
- end
110
-
111
- def take_while
112
- RecurringDateEnumerator.new(self) do |result, value|
113
- raise StopIteration unless yield(value)
114
- result << value
115
- end
116
- end
117
-
118
- def inspect
119
- ['#<RecurringDateEnumerator: 0x', object_id, '>'].join
120
- end
121
-
122
- def self.infinity(date)
123
- Enumerator.new do |y|
124
- i = date.prev_day
125
- loop { y << (i = i.next) }
126
- end
127
- end
128
- end