zakuro 0.0.0 → 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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +4 -0
  3. data/.gitignore +7 -1
  4. data/.rubocop.yml +3 -0
  5. data/Gemfile +2 -0
  6. data/Makefile +2 -0
  7. data/README.md +156 -10
  8. data/Rakefile +1 -1
  9. data/doc/gengou.md +315 -0
  10. data/doc/operation.md +25 -0
  11. data/doc/operation/csv/month.csv +202 -0
  12. data/doc/operation/operation.xlsx +0 -0
  13. data/doc/operation/transfer.rb +77 -0
  14. data/lib/zakuro/condition.rb +19 -15
  15. data/lib/zakuro/cycle/abstract_remainder.rb +3 -4
  16. data/lib/zakuro/era/japan/gengou.rb +106 -0
  17. data/lib/zakuro/era/japan/gengou/parser.rb +167 -0
  18. data/lib/zakuro/era/japan/gengou/type.rb +178 -0
  19. data/lib/zakuro/era/japan/gengou/validator.rb +236 -0
  20. data/lib/zakuro/era/japan/reki.rb +91 -0
  21. data/lib/zakuro/era/japan/yaml/set-001-until-south.yaml +1121 -0
  22. data/lib/zakuro/era/japan/yaml/set-002-from-north.yaml +485 -0
  23. data/lib/zakuro/era/japan/yaml/set-003-modern.yaml +28 -0
  24. data/lib/zakuro/era/western.rb +11 -1
  25. data/lib/zakuro/merchant.rb +3 -1
  26. data/lib/zakuro/operation/month/parser.rb +373 -0
  27. data/lib/zakuro/operation/month/type.rb +458 -0
  28. data/lib/zakuro/operation/month/validator.rb +802 -0
  29. data/lib/zakuro/operation/operation.rb +66 -0
  30. data/lib/zakuro/operation/yaml/month.yaml +6452 -0
  31. data/lib/zakuro/output/error.rb +2 -0
  32. data/lib/zakuro/output/logger.rb +2 -0
  33. data/lib/zakuro/output/response.rb +21 -19
  34. data/lib/zakuro/result/core.rb +52 -0
  35. data/lib/zakuro/result/data.rb +187 -0
  36. data/lib/zakuro/result/operation.rb +114 -0
  37. data/lib/zakuro/result/result.rb +37 -0
  38. data/lib/zakuro/{output → tools}/stringifier.rb +16 -9
  39. data/lib/zakuro/tools/typeof.rb +33 -0
  40. data/lib/zakuro/version.rb +1 -1
  41. data/lib/zakuro/version/senmyou/README.md +3 -1
  42. data/lib/zakuro/version/senmyou/base/era.rb +3 -1
  43. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +98 -0
  44. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +217 -0
  45. data/lib/zakuro/version/senmyou/base/remainder.rb +4 -4
  46. data/lib/zakuro/version/senmyou/base/solar_term.rb +20 -0
  47. data/lib/zakuro/version/senmyou/base/year.rb +52 -6
  48. data/lib/zakuro/version/senmyou/monthly/first_day.rb +44 -0
  49. data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +48 -0
  50. data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +1 -1
  51. data/lib/zakuro/version/senmyou/monthly/month.rb +136 -67
  52. data/lib/zakuro/version/senmyou/monthly/month_label.rb +87 -0
  53. data/lib/zakuro/version/senmyou/monthly/operated_month.rb +167 -0
  54. data/lib/zakuro/version/senmyou/{summary/annual_data.rb → range/annual_range.rb} +38 -40
  55. data/lib/zakuro/version/senmyou/range/full_range.rb +324 -0
  56. data/lib/zakuro/version/senmyou/range/operated_range.rb +126 -0
  57. data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +181 -0
  58. data/lib/zakuro/version/senmyou/senmyou.rb +2 -2
  59. data/lib/zakuro/version/senmyou/specifier/single_day_specifier.rb +102 -0
  60. data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +1 -1
  61. data/lib/zakuro/version/senmyou/stella/solar_average.rb +54 -32
  62. data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +3 -7
  63. data/lib/zakuro/version/senmyou/summary/single.rb +125 -0
  64. data/lib/zakuro/version_factory.rb +1 -1
  65. metadata +40 -13
  66. data/.travis.yml +0 -6
  67. data/lib/zakuro/era/gengou/set-001-until-south.yaml +0 -375
  68. data/lib/zakuro/era/gengou/set-002-from-north.yaml +0 -166
  69. data/lib/zakuro/era/gengou/set-003-modern.yaml +0 -12
  70. data/lib/zakuro/era/japan.rb +0 -630
  71. data/lib/zakuro/output/result.rb +0 -219
  72. data/lib/zakuro/version/senmyou/base/gengou.rb +0 -210
  73. data/lib/zakuro/version/senmyou/summary/gengou_data.rb +0 -294
@@ -0,0 +1,802 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative '../../era/western'
5
+
6
+ # :nodoc:
7
+ module Zakuro
8
+ #
9
+ # Operation 運用
10
+ #
11
+ module Operation
12
+ #
13
+ # Validator バリデーション
14
+ #
15
+ module Validator
16
+ #
17
+ # Types 型判定
18
+ #
19
+ module Types
20
+ EMPTY_STRING = '-'
21
+ BOOLEANS = %w[true false].freeze
22
+
23
+ #
24
+ # 有効文字列か
25
+ #
26
+ # @param [String] str 対象文字列
27
+ #
28
+ # @return [True] 有効
29
+ # @return [False] 無効
30
+ #
31
+ def self.string?(str: '')
32
+ return false if str == ''
33
+
34
+ return false unless str
35
+
36
+ str.is_a?(String)
37
+ end
38
+
39
+ #
40
+ # 有効文字列(空文字許容)か
41
+ #
42
+ # @param [String] str 対象文字列
43
+ #
44
+ # @return [True] 有効
45
+ # @return [False] 無効
46
+ #
47
+ def self.empiable_string?(str: '')
48
+ return false unless str
49
+
50
+ str.is_a?(String)
51
+ end
52
+
53
+ #
54
+ # 正数か
55
+ #
56
+ # @param [String] str 対象文字列
57
+ #
58
+ # @return [True] 正数
59
+ # @return [False] 負数
60
+ #
61
+ def self.positive?(str: '')
62
+ return true if str == EMPTY_STRING
63
+
64
+ return false unless str
65
+
66
+ /^[0-9]+$/.match?(str)
67
+ end
68
+
69
+ #
70
+ # 数値か
71
+ #
72
+ # @param [String] str 対象文字列
73
+ #
74
+ # @return [True] 数値
75
+ # @return [False] 非数値
76
+ #
77
+ def self.num?(str: '')
78
+ return true if str == EMPTY_STRING
79
+
80
+ return false unless str
81
+
82
+ /^[-0-9]+$/.match?(str)
83
+ end
84
+
85
+ #
86
+ # booleanか
87
+ #
88
+ # @param [String] str 対象文字列
89
+ #
90
+ # @return [True] boolean
91
+ # @return [False] 非boolean
92
+ #
93
+ def self.bool?(str: '')
94
+ BOOLEANS.include?(str)
95
+ end
96
+
97
+ #
98
+ # boolean(空許容)か
99
+ #
100
+ # @param [String] str 対象文字列
101
+ #
102
+ # @return [True] boolean
103
+ # @return [False] 非boolean
104
+ #
105
+ def self.empiable_bool?(str: '')
106
+ return true if str == EMPTY_STRING
107
+
108
+ bool?(str: str)
109
+ end
110
+
111
+ #
112
+ # 月差分か
113
+ #
114
+ # @param [String] str 対象文字列
115
+ #
116
+ # @return [True] 有効
117
+ # @return [False] 無効
118
+ #
119
+ def self.month_days?(str: '')
120
+ return true if str == EMPTY_STRING
121
+
122
+ return false unless str
123
+
124
+ /^[大小]$/.match?(str)
125
+ end
126
+
127
+ #
128
+ # 西暦日か
129
+ #
130
+ # @param [String] str 対象文字列
131
+ #
132
+ # @return [True] 有効
133
+ # @return [False] 無効
134
+ #
135
+ def self.western_date?(str: '')
136
+ return Western::Calendar.new if str == EMPTY_STRING
137
+
138
+ Western::Calendar.valid_date_string(str: str)
139
+ end
140
+ end
141
+
142
+ # :reek:TooManyInstanceVariables { max_instance_variables: 5 }
143
+
144
+ #
145
+ # MonthHistory 変更履歴
146
+ #
147
+ class MonthHistory
148
+ # @return [Integer] 連番
149
+ attr_reader :index
150
+ # @return [String] ID
151
+ attr_reader :id
152
+ # @return [String] 親ID
153
+ attr_reader :parend_id
154
+ # @return [String] 西暦日
155
+ attr_reader :western_date
156
+ # @return [String] 有効行
157
+ attr_reader :modified
158
+
159
+ #
160
+ # 初期化
161
+ #
162
+ # @param [Integer] index 連番
163
+ # @param [Hash<String, String>] yaml_hash yaml
164
+ # @option yaml_hash [String] :id ID
165
+ # @option yaml_hash [String] :parent_id 親ID
166
+ # @option yaml_hash [String] :western_date 西暦日
167
+ # @option yaml_hash [String] :modified 有効行
168
+ #
169
+ def initialize(index:, yaml_hash: {})
170
+ @index = index
171
+ @id = yaml_hash['id']
172
+ @parent_id = yaml_hash['parent_id']
173
+ @western_date = yaml_hash['western_date']
174
+ @modified = yaml_hash['modified']
175
+ end
176
+
177
+ # :reek:TooManyStatements { max_statements: 7 }
178
+
179
+ #
180
+ # 検証する
181
+ #
182
+ # @return [Array<String>] エラーメッセージ
183
+ #
184
+ def validate
185
+ failed = []
186
+
187
+ prefix = "[#{@index}] invalid"
188
+
189
+ failed.push("#{prefix} 'id'. #{@id}") unless id?
190
+
191
+ failed.push("#{prefix} 'parent_id'. #{@id}") unless parent_id?
192
+
193
+ failed.push("#{prefix} 'western_date'. #{@western_date}") unless western_date?
194
+
195
+ failed.push("#{prefix} 'modified'. #{@modified}") unless modified?
196
+
197
+ failed
198
+ end
199
+
200
+ def id?
201
+ Types.string?(str: @id)
202
+ end
203
+
204
+ def parent_id?
205
+ Types.string?(str: @parent_id)
206
+ end
207
+
208
+ def western_date?
209
+ Types.western_date?(str: @western_date)
210
+ end
211
+
212
+ def modified?
213
+ Types.bool?(str: @modified)
214
+ end
215
+ end
216
+
217
+ #
218
+ # Annotation 注釈
219
+ #
220
+ class Annotation
221
+ # @return [Integer] 連番
222
+ attr_reader :index
223
+ # @return [String] ID
224
+ attr_reader :id
225
+ # @return [String] 注釈内容
226
+ attr_reader :description
227
+ # @return [String] 補足
228
+ attr_reader :note
229
+
230
+ #
231
+ # 初期化
232
+ #
233
+ # @param [Integer] index 連番
234
+ # @param [Hash<String, String>] yaml_hash yaml
235
+ # @option yaml_hash [String] :id ID
236
+ # @option yaml_hash [String] :description 注釈内容
237
+ # @option yaml_hash [String] :note 補足
238
+ #
239
+ def initialize(index:, yaml_hash: {})
240
+ @index = index
241
+ @id = yaml_hash['id']
242
+ @description = yaml_hash['description']
243
+ @note = yaml_hash['note']
244
+ end
245
+
246
+ # :reek:TooManyStatements { max_statements: 6 }
247
+
248
+ #
249
+ # 検証する
250
+ #
251
+ # @return [Array<String>] エラーメッセージ
252
+ #
253
+ def validate
254
+ failed = []
255
+
256
+ prefix = "[#{@index}] invalid"
257
+
258
+ failed.push("#{prefix} 'id'. #{@id}") unless id?
259
+
260
+ failed.push("#{prefix} 'description'. #{@description}") unless description?
261
+
262
+ failed.push("#{prefix} 'note'. #{@note}") unless note?
263
+
264
+ failed
265
+ end
266
+
267
+ def id?
268
+ Types.string?(str: @id)
269
+ end
270
+
271
+ def description?
272
+ Types.empiable_string?(str: @description)
273
+ end
274
+
275
+ def note?
276
+ Types.string?(str: @note)
277
+ end
278
+ end
279
+
280
+ #
281
+ # Reference 参照
282
+ #
283
+ class Reference
284
+ # @return [Integer] 連番
285
+ attr_reader :index
286
+ # @return [String] 原文頁数
287
+ attr_reader :page
288
+ # @return [String] 原文注釈番号
289
+ attr_reader :number
290
+ # @return [String] 和暦日
291
+ attr_reader :japan_date
292
+
293
+ #
294
+ # 初期化
295
+ #
296
+ # @param [Integer] index 連番
297
+ # @param [Hash<String, String>] yaml_hash yaml
298
+ # @option yaml_hash [String] :page 原文頁数
299
+ # @option yaml_hash [String] :number 原文注釈番号
300
+ # @option yaml_hash [String] :japan_date 和暦日
301
+ #
302
+ def initialize(index:, yaml_hash: {})
303
+ @index = index
304
+ @page = yaml_hash['page']
305
+ @number = yaml_hash['number']
306
+ @japan_date = yaml_hash['japan_date']
307
+ end
308
+
309
+ # :reek:TooManyStatements { max_statements: 6 }
310
+
311
+ #
312
+ # 検証する
313
+ #
314
+ # @return [Array<String>] エラーメッセージ
315
+ #
316
+ def validate
317
+ failed = []
318
+
319
+ prefix = "[#{@index}] invalid"
320
+
321
+ failed.push("#{prefix} 'page'. #{@page}") unless page?
322
+
323
+ failed.push("#{prefix} 'number'. #{@number}") unless number?
324
+
325
+ failed.push("#{prefix} 'japan_date'. #{@japan_date}") unless japan_date?
326
+
327
+ failed
328
+ end
329
+
330
+ def page?
331
+ Types.positive?(str: @page)
332
+ end
333
+
334
+ def number?
335
+ Types.positive?(str: @number)
336
+ end
337
+
338
+ def japan_date?
339
+ Types.string?(str: @japan_date)
340
+ end
341
+ end
342
+
343
+ #
344
+ # Diffs 総差分
345
+ #
346
+ class Diffs
347
+ # @return [Integer] 連番
348
+ attr_reader :index
349
+ # @return [Hash] 月差分
350
+ attr_reader :month
351
+ # @return [Hash] 二十四節気差分
352
+ attr_reader :solar_term
353
+ # @return [String] 日差分
354
+ attr_reader :days
355
+
356
+ #
357
+ # 初期化
358
+ #
359
+ # @param [Integer] index 連番
360
+ # @param [Hash] yaml_hash yaml
361
+ # @option yaml_hash [Hash] :month 月差分
362
+ # @option yaml_hash [Hash] :solar_term 二十四節気差分
363
+ # @option yaml_hash [String] :days 日差分
364
+ #
365
+ def initialize(index:, yaml_hash: {})
366
+ @index = index
367
+ @month = Month.new(index: index, yaml_hash: yaml_hash['month'])
368
+ @solar_term = SolarTerm::Direction.new(index: index, yaml_hash: yaml_hash['solar_term'])
369
+ @days = yaml_hash['days']
370
+ end
371
+
372
+ # :reek:TooManyStatements { max_statements: 6 }
373
+
374
+ #
375
+ # 検証する
376
+ #
377
+ # @return [Array<String>] エラーメッセージ
378
+ #
379
+ def validate
380
+ failed = []
381
+
382
+ prefix = "[#{@index}] invalid"
383
+
384
+ failed += @month.validate
385
+
386
+ failed += @solar_term.validate
387
+
388
+ failed.push("#{prefix} 'days'. #{@days}") unless days?
389
+
390
+ failed
391
+ end
392
+
393
+ def days?
394
+ Types.num?(str: @days)
395
+ end
396
+ end
397
+
398
+ #
399
+ # Month 月
400
+ #
401
+ class Month
402
+ # @return [Integer] 連番
403
+ attr_reader :index
404
+ # @return [Hash] 月差分
405
+ attr_reader :number
406
+ # @return [Hash] 閏有無差分
407
+ attr_reader :leaped
408
+ # @return [String] 中気差分
409
+ attr_reader :days
410
+
411
+ #
412
+ # 初期化
413
+ #
414
+ # @param [Integer] index 連番
415
+ # @param [Hash<String, Object>] yaml_hash yaml
416
+ # @option yaml_hash [Hash] :number 月差分
417
+ # @option yaml_hash [Hash] :leaped 閏有無差分
418
+ # @option yaml_hash [String] :days 中気差分
419
+ #
420
+ def initialize(index:, yaml_hash: {})
421
+ @index = index
422
+ @number = Number.new(index: index, yaml_hash: yaml_hash['number'])
423
+ @leaped = Leaped.new(index: index, yaml_hash: yaml_hash['leaped'])
424
+ @days = Days.new(index: index, yaml_hash: yaml_hash['days'])
425
+ end
426
+
427
+ #
428
+ # 検証する
429
+ #
430
+ # @return [Array<String>] エラーメッセージ
431
+ #
432
+ def validate
433
+ failed = []
434
+
435
+ failed += @number.validate
436
+
437
+ failed += @leaped.validate
438
+
439
+ failed += @days.validate
440
+
441
+ failed
442
+ end
443
+ end
444
+
445
+ module SolarTerm
446
+ #
447
+ # Direction 二十四節気(移動)
448
+ #
449
+ class Direction
450
+ # @return [Integer] 連番
451
+ attr_reader :index
452
+ # @return [Source] 移動元
453
+ attr_reader :source
454
+ # @return [Destination] 移動先
455
+ attr_reader :destination
456
+ # @return [String] 中気差分
457
+ attr_reader :days
458
+
459
+ #
460
+ # 初期化
461
+ #
462
+ # @param [Integer] index 連番
463
+ # @param [Hash<String, Object>] yaml_hash yaml
464
+ # @option yaml_hash [Hash] :calc 移動元
465
+ # @option yaml_hash [Hash] :actual 移動先
466
+ # @option yaml_hash [String] :days 中気差分
467
+ #
468
+ def initialize(index:, yaml_hash: {})
469
+ @index = index
470
+ @source = Source.new(diff_index: index, yaml_hash: yaml_hash['calc'])
471
+ @destination = Destination.new(diff_index: index, yaml_hash: yaml_hash['actual'])
472
+ @days = yaml_hash['days']
473
+ end
474
+
475
+ def days?
476
+ Types.positive?(str: @days)
477
+ end
478
+
479
+ # :reek:TooManyStatements { max_statements: 6 }
480
+
481
+ #
482
+ # 検証する
483
+ #
484
+ # @return [Array<String>] エラーメッセージ
485
+ #
486
+ def validate
487
+ failed = []
488
+
489
+ prefix = "[#{index}][solar_term] invalid"
490
+
491
+ failed += @source.validate
492
+
493
+ failed += @destination.validate
494
+
495
+ failed.push("#{prefix} 'days'. #{@days}") unless days?
496
+
497
+ failed
498
+ end
499
+ end
500
+
501
+ #
502
+ # Source 二十四節気(移動元)
503
+ #
504
+ class Source
505
+ # @return [Integer] 連番
506
+ attr_reader :diff_index
507
+ # @return [String] 移動対象の二十四節気番号
508
+ attr_reader :index
509
+ # @return [String] 移動先の月初日
510
+ attr_reader :to
511
+ # @return [String] 十干十二支
512
+ attr_reader :zodiac_name
513
+
514
+ #
515
+ # 初期化
516
+ #
517
+ # @param [Integer] diff_index 連番
518
+ # @param [Hash<String, String>] yaml_hash yaml
519
+ # @option yaml_hash [String] :index 移動対象の二十四節気番号
520
+ # @option yaml_hash [String] :to 移動先の月初日
521
+ # @option yaml_hash [String] :zodiac_name 十干十二支
522
+ #
523
+ def initialize(diff_index:, yaml_hash: {})
524
+ @diff_index = diff_index
525
+ @index = yaml_hash['index']
526
+ @to = yaml_hash['to']
527
+ @zodiac_name = yaml_hash['zodiac_name']
528
+ end
529
+
530
+ # :reek:TooManyStatements { max_statements: 6 }
531
+
532
+ #
533
+ # 検証する
534
+ #
535
+ # @return [Array<String>] エラーメッセージ
536
+ #
537
+ def validate
538
+ failed = []
539
+
540
+ prefix = "[#{@diff_index}][solar_term.calc] invalid"
541
+
542
+ failed.push("#{prefix} 'index'. #{@index}") unless index?
543
+
544
+ failed.push("#{prefix} 'to'. #{@to}") unless to?
545
+
546
+ failed.push("#{prefix} 'zodiac_name'. #{@zodiac_name}") unless zodiac_name?
547
+
548
+ failed
549
+ end
550
+
551
+ def index?
552
+ Types.positive?(str: @index)
553
+ end
554
+
555
+ def to?
556
+ Types.western_date?(str: @to)
557
+ end
558
+
559
+ def zodiac_name?
560
+ Types.string?(str: @zodiac_name)
561
+ end
562
+ end
563
+
564
+ #
565
+ # Destination 二十四節気(移動先)
566
+ #
567
+ class Destination
568
+ # @return [Integer] 連番
569
+ attr_reader :diff_index
570
+ # @return [String] 移動対象の二十四節気番号
571
+ attr_reader :index
572
+ # @return [String] 移動元の月初日
573
+ attr_reader :from
574
+ # @return [String] 十干十二支
575
+ attr_reader :zodiac_name
576
+
577
+ #
578
+ # 初期化
579
+ #
580
+ # @param [Integer] diff_index 連番
581
+ # @param [Hash<String, String>] yaml_hash yaml
582
+ # @option yaml_hash [String] :index 移動対象の二十四節気番号
583
+ # @option yaml_hash [String] :from 移動元の月初日
584
+ # @option yaml_hash [String] :zodiac_name 十干十二支
585
+ #
586
+ def initialize(diff_index:, yaml_hash: {})
587
+ @diff_index = diff_index
588
+ @index = yaml_hash['index']
589
+ @from = yaml_hash['from']
590
+ @zodiac_name = yaml_hash['zodiac_name']
591
+ end
592
+
593
+ # :reek:TooManyStatements { max_statements: 6 }
594
+
595
+ #
596
+ # 検証する
597
+ #
598
+ # @return [Array<String>] エラーメッセージ
599
+ #
600
+ def validate
601
+ failed = []
602
+
603
+ prefix = "[#{@diff_index}][solar_term.actual] invalid"
604
+
605
+ failed.push("#{prefix} 'index'. #{@index}") unless index?
606
+
607
+ failed.push("#{prefix} 'from'. #{@from}") unless from?
608
+
609
+ failed.push("#{prefix} 'zodiac_name'. #{@zodiac_name}") unless zodiac_name?
610
+
611
+ failed
612
+ end
613
+
614
+ def index?
615
+ Types.positive?(str: @index)
616
+ end
617
+
618
+ def from?
619
+ Types.western_date?(str: @from)
620
+ end
621
+
622
+ def zodiac_name?
623
+ Types.string?(str: @zodiac_name)
624
+ end
625
+ end
626
+ end
627
+
628
+ #
629
+ # Number 月
630
+ #
631
+ class Number
632
+ NAME = 'number'
633
+
634
+ # @return [Integer] 連番
635
+ attr_reader :index
636
+ # @return [String] 計算
637
+ attr_reader :calc
638
+ # @return [String] 運用
639
+ attr_reader :actual
640
+
641
+ #
642
+ # 初期化
643
+ #
644
+ # @param [Integer] index 連番
645
+ # @param [Hash<String, String>] yaml_hash yaml
646
+ # @option yaml_hash [String] :calc 計算
647
+ # @option yaml_hash [String] :actual 運用
648
+ #
649
+ def initialize(index:, yaml_hash: {})
650
+ @index = index
651
+ @calc = yaml_hash['calc']
652
+ @actual = yaml_hash['actual']
653
+ end
654
+
655
+ #
656
+ # 検証する
657
+ #
658
+ # @return [Array<String>] エラーメッセージ
659
+ #
660
+ def validate
661
+ failed = []
662
+
663
+ prefix = "[#{@index}][#{NAME}] invalid"
664
+
665
+ failed.push("#{prefix} 'calc'. #{@calc}") unless calc?
666
+
667
+ failed.push("#{prefix} 'actual'. #{@actual}") unless actual?
668
+
669
+ failed
670
+ end
671
+
672
+ def calc?
673
+ Types.positive?(str: @calc)
674
+ end
675
+
676
+ def actual?
677
+ Types.positive?(str: @actual)
678
+ end
679
+ end
680
+
681
+ #
682
+ # Leaped 閏有無
683
+ #
684
+ class Leaped
685
+ NAME = 'leaped'
686
+
687
+ # @return [Integer] 連番
688
+ attr_reader :index
689
+ # @return [String] 計算
690
+ attr_reader :calc
691
+ # @return [String] 運用
692
+ attr_reader :actual
693
+
694
+ #
695
+ # 初期化
696
+ #
697
+ # @param [Integer] index 連番
698
+ # @param [Hash<String, String>] yaml_hash yaml
699
+ # @option yaml_hash [String] :calc 計算
700
+ # @option yaml_hash [String] :actual 運用
701
+ #
702
+ def initialize(index:, yaml_hash: {})
703
+ @index = index
704
+ @calc = yaml_hash['calc']
705
+ @actual = yaml_hash['actual']
706
+ end
707
+
708
+ #
709
+ # 検証する
710
+ #
711
+ # @return [Array<String>] エラーメッセージ
712
+ #
713
+ def validate
714
+ failed = []
715
+
716
+ prefix = "[#{@index}][#{NAME}] invalid"
717
+
718
+ failed.push("#{prefix} 'calc'. #{@calc}") unless calc?
719
+
720
+ failed.push("#{prefix} 'actual'. #{@actual}") unless actual?
721
+
722
+ failed
723
+ end
724
+
725
+ def calc?
726
+ Types.empiable_bool?(str: @calc)
727
+ end
728
+
729
+ def actual?
730
+ Types.empiable_bool?(str: @actual)
731
+ end
732
+ end
733
+
734
+ #
735
+ # Days 月日数(大小)
736
+ #
737
+ class Days
738
+ NAME = 'days'
739
+
740
+ # @return [Integer] 連番
741
+ attr_reader :index
742
+ # @return [String] 計算
743
+ attr_reader :calc
744
+ # @return [String] 運用
745
+ attr_reader :actual
746
+
747
+ #
748
+ # 初期化
749
+ #
750
+ # @param [Integer] index 連番
751
+ # @param [Hash<String, String>] yaml_hash yaml
752
+ # @option yaml_hash [String] :calc 計算
753
+ # @option yaml_hash [String] :actual 運用
754
+ #
755
+ def initialize(index:, yaml_hash: {})
756
+ @index = index
757
+ @calc = yaml_hash['calc']
758
+ @actual = yaml_hash['actual']
759
+ end
760
+
761
+ #
762
+ # 検証する
763
+ #
764
+ # @return [Array<String>] エラーメッセージ
765
+ #
766
+ def validate
767
+ failed = []
768
+
769
+ prefix = "[#{@index}][#{NAME}] invalid"
770
+
771
+ failed.push("#{prefix} 'calc'. #{@calc}") unless calc?
772
+
773
+ failed.push("#{prefix} 'actual'. #{@actual}") unless actual?
774
+
775
+ failed
776
+ end
777
+
778
+ def calc?
779
+ Types.month_days?(str: @calc)
780
+ end
781
+
782
+ def actual?
783
+ Types.month_days?(str: @actual)
784
+ end
785
+ end
786
+
787
+ # :reek:TooManyStatements { max_statements: 7 }
788
+
789
+ def self.run(yaml_hash: {})
790
+ failed = []
791
+ yaml_hash.each_with_index do |history, index|
792
+ failed += MonthHistory.new(index: index, yaml_hash: history).validate
793
+ failed += Annotation.new(index: index, yaml_hash: history).validate
794
+ failed += Reference.new(index: index, yaml_hash: history).validate
795
+ failed += Diffs.new(index: index, yaml_hash: history['diffs']).validate
796
+ end
797
+
798
+ failed
799
+ end
800
+ end
801
+ end
802
+ end