zakuro 0.0.3 → 0.1.0

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +85 -43
  3. data/doc/operation.md +25 -0
  4. data/doc/operation/csv/month.csv +202 -0
  5. data/doc/operation/operation.xlsx +0 -0
  6. data/doc/operation/transfer.rb +73 -0
  7. data/lib/zakuro/era/japan/gengou.rb +106 -0
  8. data/lib/zakuro/era/japan/gengou/parser.rb +169 -0
  9. data/lib/zakuro/era/japan/gengou/type.rb +178 -0
  10. data/lib/zakuro/era/japan/gengou/validator.rb +234 -0
  11. data/lib/zakuro/era/japan/reki.rb +91 -0
  12. data/lib/zakuro/era/{gengou → japan/yaml}/set-001-until-south.yaml +0 -0
  13. data/lib/zakuro/era/{gengou → japan/yaml}/set-002-from-north.yaml +0 -0
  14. data/lib/zakuro/era/{gengou → japan/yaml}/set-003-modern.yaml +0 -0
  15. data/lib/zakuro/era/western.rb +1 -1
  16. data/lib/zakuro/operation/month/parser.rb +277 -0
  17. data/lib/zakuro/operation/month/type.rb +452 -0
  18. data/lib/zakuro/operation/month/validator.rb +498 -0
  19. data/lib/zakuro/operation/operation.rb +45 -0
  20. data/lib/zakuro/operation/yaml/month.yaml +6452 -0
  21. data/lib/zakuro/output/error.rb +2 -0
  22. data/lib/zakuro/output/logger.rb +2 -0
  23. data/lib/zakuro/output/response.rb +17 -15
  24. data/lib/zakuro/result/core.rb +52 -0
  25. data/lib/zakuro/result/data.rb +187 -0
  26. data/lib/zakuro/result/operation.rb +86 -0
  27. data/lib/zakuro/result/result.rb +37 -0
  28. data/lib/zakuro/{output → tools}/stringifier.rb +14 -7
  29. data/lib/zakuro/tools/typeof.rb +33 -0
  30. data/lib/zakuro/version.rb +1 -1
  31. data/lib/zakuro/version/senmyou/base/era.rb +1 -1
  32. data/lib/zakuro/version/senmyou/base/multi_gengou.rb +1 -1
  33. data/lib/zakuro/version/senmyou/base/multi_gengou_roller.rb +13 -1
  34. data/lib/zakuro/version/senmyou/base/solar_term.rb +10 -0
  35. data/lib/zakuro/version/senmyou/monthly/first_day.rb +44 -0
  36. data/lib/zakuro/version/senmyou/monthly/initialized_month.rb +48 -0
  37. data/lib/zakuro/version/senmyou/monthly/month.rb +127 -68
  38. data/lib/zakuro/version/senmyou/monthly/month_label.rb +87 -0
  39. data/lib/zakuro/version/senmyou/monthly/operated_month.rb +167 -0
  40. data/lib/zakuro/version/senmyou/{summary → range}/annual_range.rb +20 -23
  41. data/lib/zakuro/version/senmyou/{summary → range}/full_range.rb +102 -2
  42. data/lib/zakuro/version/senmyou/range/operated_range.rb +105 -0
  43. data/lib/zakuro/version/senmyou/range/operated_solar_terms.rb +163 -0
  44. data/lib/zakuro/version/senmyou/senmyou.rb +2 -2
  45. data/lib/zakuro/version/senmyou/{summary/specifier.rb → specifier/single_day_specifier.rb} +13 -14
  46. data/lib/zakuro/version/senmyou/stella/solar_average.rb +3 -7
  47. data/lib/zakuro/version/senmyou/summary/single.rb +71 -0
  48. data/lib/zakuro/version_factory.rb +1 -1
  49. metadata +35 -11
  50. data/lib/zakuro/era/japan.rb +0 -664
  51. data/lib/zakuro/output/result.rb +0 -225
@@ -0,0 +1,452 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require_relative '../../era/western'
5
+ require_relative './validator'
6
+
7
+ # :nodoc:
8
+ module Zakuro
9
+ #
10
+ # Operation 運用
11
+ #
12
+ module Operation
13
+ #
14
+ # 日(差分)無効値
15
+ #
16
+ INVALID_DAY_VALUE = -30
17
+
18
+ #
19
+ # MonthHistory 変更履歴
20
+ #
21
+ class MonthHistory
22
+ # @return [String] ID
23
+ attr_reader :id
24
+ # @return [String] 親ID
25
+ attr_reader :parent_id
26
+ # @return [Reference] 参照
27
+ attr_reader :reference
28
+ # @return [Western::Calendar] 西暦日
29
+ attr_reader :western_date
30
+ # @return [Array<Annotation>] 注釈
31
+ attr_reader :annotations
32
+ # @return [Diffs] 総差分
33
+ attr_reader :diffs
34
+
35
+ #
36
+ # 初期化
37
+ #
38
+ # @param [String] id ID
39
+ # @param [String] parent_id 親ID
40
+ # @param [Reference] reference 参照
41
+ # @param [Western::Calendar] western_date 西暦日
42
+ # @param [Array<Annotation>] annotations 注釈
43
+ # @param [Diffs] diffs 総差分
44
+ #
45
+ def initialize(id: '', parent_id: '', reference: Reference.new,
46
+ western_date: Western::Calendar.new, annotations: [], diffs: Diffs.new)
47
+ @id = id
48
+ @parent_id = parent_id
49
+ @reference = reference
50
+ @western_date = western_date
51
+ @annotations = annotations
52
+ @diffs = diffs
53
+ end
54
+
55
+ #
56
+ # 無効か
57
+ #
58
+ # @return [True] 無効
59
+ # @return [False] 有効
60
+ #
61
+ def invalid?
62
+ id == ''
63
+ end
64
+ end
65
+
66
+ #
67
+ # Annotation 注釈
68
+ #
69
+ class Annotation
70
+ # @return [String] ID
71
+ attr_reader :id
72
+ # @return [String] 内容
73
+ attr_reader :description
74
+ # @return [String] 正誤訂正(zakuro)
75
+ attr_reader :note
76
+
77
+ #
78
+ # 初期化
79
+ #
80
+ # @param [String] id ID
81
+ # @param [String] description 内容
82
+ # @param [String] note 正誤訂正(zakuro)
83
+ #
84
+ def initialize(id: '', description: '', note: '')
85
+ @id = id
86
+ @description = description
87
+ @note = note
88
+ end
89
+
90
+ #
91
+ # 無効か
92
+ #
93
+ # @return [True] 無効
94
+ # @return [False] 有効
95
+ #
96
+ def invalid?
97
+ return true if @id == ''
98
+
99
+ @description == '' && @note == ''
100
+ end
101
+ end
102
+
103
+ #
104
+ # Reference 参照
105
+ #
106
+ class Reference
107
+ # @return [Integer] 頁数
108
+ attr_reader :page
109
+ # @return [Integer] 注釈番号
110
+ attr_reader :number
111
+ # @return [String] 和暦日
112
+ attr_reader :japan_date
113
+
114
+ #
115
+ # 初期化
116
+ #
117
+ # @param [Integer] page 頁数
118
+ # @param [Integer] number 注釈番号
119
+ # @param [String] japan_date 和暦日
120
+ #
121
+ def initialize(page: -1, number: -1, japan_date: '')
122
+ @page = page
123
+ @number = number
124
+ @japan_date = japan_date
125
+ end
126
+
127
+ #
128
+ # 無効か
129
+ #
130
+ # @return [True] 無効
131
+ # @return [False] 有効
132
+ #
133
+ def invalid?
134
+ page == -1
135
+ end
136
+ end
137
+
138
+ #
139
+ # Diffs 総差分
140
+ #
141
+ class Diffs
142
+ # @return [Month] 月差分
143
+ attr_reader :month
144
+ # @return [SolarTerm::Direction] 二十四節気差分
145
+ attr_reader :solar_term
146
+ # @return [Integer] 日差分
147
+ attr_reader :days
148
+
149
+ #
150
+ # 初期化
151
+ #
152
+ # @param [Month] month 月差分
153
+ # @param [SolarTerm::Direction] solar_term 二十四節気差分
154
+ # @param [Integer] days 日差分
155
+ #
156
+ def initialize(month: Month.new, solar_term: SolarTerm::Direction.new,
157
+ days: INVALID_DAY_VALUE)
158
+ @month = month
159
+ @solar_term = solar_term
160
+ @days = days
161
+ end
162
+
163
+ #
164
+ # 日差分が無効か
165
+ #
166
+ # @return [True] 無効
167
+ # @return [False] 有効
168
+ #
169
+ def invalid_days?
170
+ @days == INVALID_DAY_VALUE
171
+ end
172
+ end
173
+
174
+ #
175
+ # Month 月差分
176
+ #
177
+ class Month
178
+ # @return [Number] 月
179
+ attr_reader :number
180
+ # @return [Leaped] 閏有無
181
+ attr_reader :leaped
182
+ # @return [Days] 月の大小
183
+ attr_reader :days
184
+
185
+ # :reek:BooleanParameter
186
+
187
+ #
188
+ # 初期化
189
+ #
190
+ # @param [Number] number 月
191
+ # @param [Leaped] leaped 閏有無
192
+ # @param [Days] days 月の大小
193
+ #
194
+ def initialize(number: Number.new, leaped: Leaped.new, days: Days.new)
195
+ @number = number
196
+ @leaped = leaped
197
+ @days = days
198
+ end
199
+
200
+ #
201
+ # 無効か
202
+ #
203
+ # @return [True] 無効
204
+ # @return [False] 有効
205
+ #
206
+ def invalid?
207
+ number == -1
208
+ end
209
+ end
210
+
211
+ #
212
+ # 二十四節気
213
+ #
214
+ module SolarTerm
215
+ #
216
+ # Direction 二十四節気(移動)
217
+ #
218
+ class Direction
219
+ # @return [Source] 二十四節気(移動元)
220
+ attr_reader :source
221
+ # @return [Destination] 二十四節気(移動先)
222
+ attr_reader :destination
223
+ # @return [Integer] 大余差分
224
+ attr_reader :days
225
+
226
+ #
227
+ # 初期化
228
+ #
229
+ # @param [Source] source 二十四節気(移動元)
230
+ # @param [Destination] destination 二十四節気(移動先)
231
+ # @param [Integer] day 大余差分
232
+ #
233
+ def initialize(source: Source.new, destination: Destination.new,
234
+ days: INVALID_DAY_VALUE)
235
+ @source = source
236
+ @destination = destination
237
+ @days = days
238
+ end
239
+
240
+ #
241
+ # 無効か(大余差分)
242
+ #
243
+ # @return [True] 無効
244
+ # @return [False] 有効
245
+ #
246
+ def invalid_days?
247
+ @days == INVALID_DAY_VALUE
248
+ end
249
+
250
+ #
251
+ # 無効か
252
+ #
253
+ # @return [True] 無効
254
+ # @return [False] 有効
255
+ #
256
+ def invalid?
257
+ @source.invalid? && @destination.invalid?
258
+ end
259
+ end
260
+
261
+ #
262
+ # Source 二十四節気(移動元)
263
+ #
264
+ class Source
265
+ # @return [Integer] 二十四節気番号
266
+ attr_reader :index
267
+ # @return [Western::Calendar] 移動先の月初日
268
+ attr_reader :to
269
+ # @return [String] 十干十二支
270
+ attr_reader :zodiac_name
271
+
272
+ #
273
+ # 初期化
274
+ #
275
+ # @param [Integer] index 二十四節気番号
276
+ # @param [Western::Calendar] to 移動先の月初日
277
+ # @param [String] zodiac_name 十干十二支
278
+ #
279
+ def initialize(index: -1, to: Western::Calendar.new, zodiac_name: '')
280
+ @index = index
281
+ @to = to
282
+ @zodiac_name = zodiac_name
283
+ end
284
+
285
+ #
286
+ # 無効か
287
+ #
288
+ # @return [True] 無効
289
+ # @return [False] 有効
290
+ #
291
+ def invalid?
292
+ @index == -1
293
+ end
294
+ end
295
+
296
+ #
297
+ # Destination 二十四節気(移動先)
298
+ #
299
+ class Destination
300
+ # @return [Integer] 二十四節気番号
301
+ attr_reader :index
302
+ # @return [Western::Calendar] 移動元の月初日
303
+ attr_reader :from
304
+ # @return [String] 十干十二支
305
+ attr_reader :zodiac_name
306
+
307
+ #
308
+ # 初期化
309
+ #
310
+ # @param [Integer] index 二十四節気番号
311
+ # @param [Western::Calendar] from 移動元の月初日
312
+ # @param [String] zodiac_name 十干十二支
313
+ #
314
+ def initialize(index: -1, from: Western::Calendar.new, zodiac_name: '')
315
+ @index = index
316
+ @from = from
317
+ @zodiac_name = zodiac_name
318
+ end
319
+
320
+ #
321
+ # 無効か
322
+ #
323
+ # @return [True] 無効
324
+ # @return [False] 有効
325
+ #
326
+ def invalid?
327
+ @index == -1
328
+ end
329
+ end
330
+ end
331
+
332
+ #
333
+ # Number 月
334
+ #
335
+ class Number
336
+ # @return [Integer] 計算
337
+ attr_reader :calc
338
+ # @return [Integer] 運用
339
+ attr_reader :actual
340
+
341
+ #
342
+ # 初期化
343
+ #
344
+ # @param [Integer] calc 計算
345
+ # @param [Integer] actual 運用
346
+ #
347
+ def initialize(calc: -1, actual: -1)
348
+ @calc = calc
349
+ @actual = actual
350
+ end
351
+
352
+ #
353
+ # 無効か
354
+ #
355
+ # @return [True] 無効
356
+ # @return [False] 有効
357
+ #
358
+ def invalid?
359
+ @calc == -1 || @actual == -1
360
+ end
361
+ end
362
+
363
+ #
364
+ # Leaped 閏有無
365
+ #
366
+ class Leaped
367
+ # @return [True, False] 計算
368
+ attr_reader :calc
369
+ # @return [True, False] 運用
370
+ attr_reader :actual
371
+
372
+ # :reek:BooleanParameter
373
+
374
+ #
375
+ # 初期化
376
+ #
377
+ # @param [True, False] calc 計算
378
+ # @param [True, False] actual 運用
379
+ #
380
+ def initialize(calc: false, actual: false)
381
+ @calc = calc
382
+ @actual = actual
383
+ end
384
+
385
+ #
386
+ # 無効か
387
+ #
388
+ # @return [True] 無効(設定値なし)
389
+ # @return [False] 有効
390
+ #
391
+ def invalid?
392
+ !@calc && !@actual
393
+ end
394
+ end
395
+
396
+ #
397
+ # Days 月大小
398
+ #
399
+ class Days
400
+ # @return [String] 29日
401
+ SMALL = '小'
402
+ # @return [String] 30日
403
+ BIG = '大'
404
+
405
+ # @return [String] 計算
406
+ attr_reader :calc
407
+ # @return [String] 運用
408
+ attr_reader :actual
409
+
410
+ #
411
+ # 初期化
412
+ #
413
+ # @param [String] calc 計算
414
+ # @param [String] actual 運用
415
+ #
416
+ def initialize(calc: '小', actual: '小')
417
+ @calc = calc
418
+ @actual = actual
419
+ end
420
+
421
+ #
422
+ # 計算値が大か
423
+ #
424
+ # @return [True] 大
425
+ # @return [False] 小
426
+ #
427
+ def many_days_calc?
428
+ @calc == BIG
429
+ end
430
+
431
+ #
432
+ # 運用値が大か
433
+ #
434
+ # @return [True] 大
435
+ # @return [False] 小
436
+ #
437
+ def many_days_actual?
438
+ @actual == BIG
439
+ end
440
+
441
+ #
442
+ # 無効か
443
+ #
444
+ # @return [True] 無効(差分なし/設定値なし)
445
+ # @return [False] 有効
446
+ #
447
+ def invalid?
448
+ @calc == @actual
449
+ end
450
+ end
451
+ end
452
+ end
@@ -0,0 +1,498 @@
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
+ # :reek:NilCheck
24
+
25
+ def self.string?(str: '')
26
+ !str.nil? && !str.empty? && str.is_a?(String)
27
+ end
28
+
29
+ # :reek:NilCheck
30
+
31
+ def self.empiable_string?(str: '')
32
+ !str.nil? && str.is_a?(String)
33
+ end
34
+
35
+ # :reek:NilCheck
36
+
37
+ def self.positive?(str: '')
38
+ return true if str == EMPTY_STRING
39
+
40
+ !str.nil? && !str.empty? && /^[0-9]+$/.match?(str)
41
+ end
42
+
43
+ # :reek:NilCheck
44
+
45
+ def self.num?(str: '')
46
+ return true if str == EMPTY_STRING
47
+
48
+ !str.nil? && !str.empty? && /^[-0-9]+$/.match?(str)
49
+ end
50
+
51
+ def self.bool?(str: '')
52
+ BOOLEANS.include?(str)
53
+ end
54
+
55
+ def self.empiable_bool?(str: '')
56
+ return true if str == EMPTY_STRING
57
+
58
+ bool?(str: str)
59
+ end
60
+
61
+ def self.month_days?(str: '')
62
+ return true if str == EMPTY_STRING
63
+
64
+ !str.nil? && !str.empty? && /^[大小]$/.match?(str)
65
+ end
66
+
67
+ def self.western_date?(str: '')
68
+ return Western::Calendar.new if str == EMPTY_STRING
69
+
70
+ Western::Calendar.valid_date_string(str: str)
71
+ end
72
+ end
73
+
74
+ #
75
+ # MonthHistory 変更履歴
76
+ #
77
+ class MonthHistory
78
+ attr_reader :index, :id, :parend_id, :western_date, :modified
79
+
80
+ def initialize(index:, yaml_hash: {})
81
+ @index = index
82
+ @id = yaml_hash['id']
83
+ @parent_id = yaml_hash['parent_id']
84
+ @western_date = yaml_hash['western_date']
85
+ @modified = yaml_hash['modified']
86
+ end
87
+
88
+ def validate
89
+ failed = []
90
+
91
+ prefix = "[#{@index}] invalid"
92
+
93
+ failed.push("#{prefix} 'id'. #{@id}") unless id?
94
+
95
+ failed.push("#{prefix} 'parent_id'. #{@id}") unless parent_id?
96
+
97
+ failed.push("#{prefix} 'western_date'. #{@western_date}") unless western_date?
98
+
99
+ failed.push("#{prefix} 'modified'. #{@modified}") unless modified?
100
+
101
+ failed
102
+ end
103
+
104
+ def id?
105
+ Types.string?(str: @id)
106
+ end
107
+
108
+ def parent_id?
109
+ Types.string?(str: @parent_id)
110
+ end
111
+
112
+ def western_date?
113
+ Types.western_date?(str: @western_date)
114
+ end
115
+
116
+ def modified?
117
+ Types.bool?(str: @modified)
118
+ end
119
+ end
120
+
121
+ #
122
+ # Annotation 注釈
123
+ #
124
+ class Annotation
125
+ attr_reader :index, :id, :description, :note
126
+
127
+ def initialize(index:, yaml_hash: {})
128
+ @index = index
129
+ @id = yaml_hash['id']
130
+ @description = yaml_hash['description']
131
+ @note = yaml_hash['note']
132
+ end
133
+
134
+ def validate
135
+ failed = []
136
+
137
+ prefix = "[#{@index}] invalid"
138
+
139
+ failed.push("#{prefix} 'id'. #{@id}") unless id?
140
+
141
+ failed.push("#{prefix} 'description'. #{@description}") unless description?
142
+
143
+ failed.push("#{prefix} 'note'. #{@note}") unless note?
144
+
145
+ failed
146
+ end
147
+
148
+ def id?
149
+ Types.string?(str: @id)
150
+ end
151
+
152
+ def description?
153
+ Types.empiable_string?(str: @description)
154
+ end
155
+
156
+ def note?
157
+ Types.string?(str: @note)
158
+ end
159
+ end
160
+
161
+ #
162
+ # Reference 参照
163
+ #
164
+ class Reference
165
+ attr_reader :index, :page, :number, :japan_date
166
+
167
+ def initialize(index:, yaml_hash: {})
168
+ @index = index
169
+ @page = yaml_hash['page']
170
+ @number = yaml_hash['number']
171
+ @japan_date = yaml_hash['japan_date']
172
+ end
173
+
174
+ def validate
175
+ failed = []
176
+
177
+ prefix = "[#{@index}] invalid"
178
+
179
+ failed.push("#{prefix} 'page'. #{@page}") unless page?
180
+
181
+ failed.push("#{prefix} 'number'. #{@number}") unless number?
182
+
183
+ failed.push("#{prefix} 'japan_date'. #{@japan_date}") unless japan_date?
184
+
185
+ failed
186
+ end
187
+
188
+ def page?
189
+ Types.positive?(str: @page)
190
+ end
191
+
192
+ def number?
193
+ Types.positive?(str: @number)
194
+ end
195
+
196
+ def japan_date?
197
+ Types.string?(str: @japan_date)
198
+ end
199
+ end
200
+
201
+ #
202
+ # Diffs 総差分
203
+ #
204
+ class Diffs
205
+ attr_reader :index, :month, :solar_term, :days
206
+
207
+ def initialize(index:, yaml_hash: {})
208
+ @index = index
209
+ @month = Month.new(index: index, yaml_hash: yaml_hash['month'])
210
+ @solar_term = SolarTerm::Direction.new(index: index, yaml_hash: yaml_hash['solar_term'])
211
+ @days = yaml_hash['days']
212
+ end
213
+
214
+ def validate
215
+ failed = []
216
+
217
+ prefix = "[#{@index}] invalid"
218
+
219
+ failed += @month.validate
220
+
221
+ failed += @solar_term.validate
222
+
223
+ failed.push("#{prefix} 'days'. #{@days}") unless days?
224
+
225
+ failed
226
+ end
227
+
228
+ def days?
229
+ Types.num?(str: @days)
230
+ end
231
+ end
232
+
233
+ #
234
+ # Month 月
235
+ #
236
+ class Month
237
+ attr_reader :index, :number, :leaped, :days
238
+
239
+ def initialize(index:, yaml_hash: {})
240
+ @index = index
241
+ @number = Number.new(index: index, yaml_hash: yaml_hash['number'])
242
+ @leaped = Leaped.new(index: index, yaml_hash: yaml_hash['leaped'])
243
+ @days = Days.new(index: index, yaml_hash: yaml_hash['days'])
244
+ end
245
+
246
+ def validate
247
+ failed = []
248
+
249
+ failed += @number.validate
250
+
251
+ failed += @leaped.validate
252
+
253
+ failed += @days.validate
254
+
255
+ failed
256
+ end
257
+ end
258
+
259
+ module SolarTerm
260
+ #
261
+ # Direction 二十四節気(移動)
262
+ #
263
+ class Direction
264
+ attr_reader :index, :source, :destination, :days
265
+
266
+ #
267
+ # 初期化
268
+ #
269
+ # @param [Source] source 二十四節気(移動元)
270
+ # @param [Destination] destination 二十四節気(移動先)
271
+ # @param [Integer] day 大余差分
272
+ #
273
+ def initialize(index:, yaml_hash: {})
274
+ @index = index
275
+ @source = Source.new(diff_index: index, yaml_hash: yaml_hash['calc'])
276
+ @destination = Destination.new(diff_index: index, yaml_hash: yaml_hash['actual'])
277
+ @days = yaml_hash['days']
278
+ end
279
+
280
+ def days?
281
+ Types.positive?(str: @days)
282
+ end
283
+
284
+ def validate
285
+ failed = []
286
+
287
+ prefix = "[#{index}][solar_term] invalid"
288
+
289
+ failed += @source.validate
290
+
291
+ failed += @destination.validate
292
+
293
+ failed.push("#{prefix} 'days'. #{@days}") unless days?
294
+
295
+ failed
296
+ end
297
+ end
298
+
299
+ #
300
+ # Source 二十四節気(移動元)
301
+ #
302
+ class Source
303
+ attr_reader :diff_index, :index, :to, :zodiac_name
304
+
305
+ def initialize(diff_index:, yaml_hash: {})
306
+ @diff_index = diff_index
307
+ @index = yaml_hash['index']
308
+ @to = yaml_hash['to']
309
+ @zodiac_name = yaml_hash['zodiac_name']
310
+ end
311
+
312
+ def validate
313
+ failed = []
314
+
315
+ prefix = "[#{@diff_index}][solar_term.calc] invalid"
316
+
317
+ failed.push("#{prefix} 'index'. #{@index}") unless index?
318
+
319
+ failed.push("#{prefix} 'to'. #{@to}") unless to?
320
+
321
+ failed.push("#{prefix} 'zodiac_name'. #{@zodiac_name}") unless zodiac_name?
322
+
323
+ failed
324
+ end
325
+
326
+ def index?
327
+ Types.positive?(str: @index)
328
+ end
329
+
330
+ def to?
331
+ Types.western_date?(str: @to)
332
+ end
333
+
334
+ def zodiac_name?
335
+ Types.string?(str: @zodiac_name)
336
+ end
337
+ end
338
+
339
+ #
340
+ # Destination 二十四節気(移動先)
341
+ #
342
+ class Destination
343
+ attr_reader :diff_index, :index, :from, :zodiac_name
344
+
345
+ def initialize(diff_index:, yaml_hash: {})
346
+ @diff_index = diff_index
347
+ @index = yaml_hash['index']
348
+ @from = yaml_hash['from']
349
+ @zodiac_name = yaml_hash['zodiac_name']
350
+ end
351
+
352
+ def validate
353
+ failed = []
354
+
355
+ prefix = "[#{@diff_index}][solar_term.actual] invalid"
356
+
357
+ failed.push("#{prefix} 'index'. #{@index}") unless index?
358
+
359
+ failed.push("#{prefix} 'from'. #{@from}") unless from?
360
+
361
+ failed.push("#{prefix} 'zodiac_name'. #{@zodiac_name}") unless zodiac_name?
362
+
363
+ failed
364
+ end
365
+
366
+ def index?
367
+ Types.positive?(str: @index)
368
+ end
369
+
370
+ def from?
371
+ Types.western_date?(str: @from)
372
+ end
373
+
374
+ def zodiac_name?
375
+ Types.string?(str: @zodiac_name)
376
+ end
377
+ end
378
+ end
379
+
380
+ #
381
+ # Number 月
382
+ #
383
+ class Number
384
+ NAME = 'number'
385
+
386
+ attr_reader :index, :calc, :actual
387
+
388
+ def initialize(index:, yaml_hash: {})
389
+ @index = index
390
+ @calc = yaml_hash['calc']
391
+ @actual = yaml_hash['actual']
392
+ end
393
+
394
+ def validate
395
+ failed = []
396
+
397
+ prefix = "[#{@index}][#{NAME}] invalid"
398
+
399
+ failed.push("#{prefix} 'calc'. #{@calc}") unless calc?
400
+
401
+ failed.push("#{prefix} 'actual'. #{@actual}") unless actual?
402
+
403
+ failed
404
+ end
405
+
406
+ def calc?
407
+ Types.positive?(str: @calc)
408
+ end
409
+
410
+ def actual?
411
+ Types.positive?(str: @actual)
412
+ end
413
+ end
414
+
415
+ #
416
+ # Leaped 閏有無
417
+ #
418
+ class Leaped
419
+ NAME = 'leaped'
420
+
421
+ attr_reader :index, :calc, :actual
422
+
423
+ def initialize(index:, yaml_hash: {})
424
+ @index = index
425
+ @calc = yaml_hash['calc']
426
+ @actual = yaml_hash['actual']
427
+ end
428
+
429
+ def validate
430
+ failed = []
431
+
432
+ prefix = "[#{@index}][#{NAME}] invalid"
433
+
434
+ failed.push("#{prefix} 'calc'. #{@calc}") unless calc?
435
+
436
+ failed.push("#{prefix} 'actual'. #{@actual}") unless actual?
437
+
438
+ failed
439
+ end
440
+
441
+ def calc?
442
+ Types.empiable_bool?(str: @calc)
443
+ end
444
+
445
+ def actual?
446
+ Types.empiable_bool?(str: @actual)
447
+ end
448
+ end
449
+
450
+ #
451
+ # 月日数(大小)
452
+ #
453
+ class Days
454
+ NAME = 'days'
455
+
456
+ attr_reader :index, :calc, :actual
457
+
458
+ def initialize(index:, yaml_hash: {})
459
+ @index = index
460
+ @calc = yaml_hash['calc']
461
+ @actual = yaml_hash['actual']
462
+ end
463
+
464
+ def validate
465
+ failed = []
466
+
467
+ prefix = "[#{@index}][#{NAME}] invalid"
468
+
469
+ failed.push("#{prefix} 'calc'. #{@calc}") unless calc?
470
+
471
+ failed.push("#{prefix} 'actual'. #{@actual}") unless actual?
472
+
473
+ failed
474
+ end
475
+
476
+ def calc?
477
+ Types.month_days?(str: @calc)
478
+ end
479
+
480
+ def actual?
481
+ Types.month_days?(str: @actual)
482
+ end
483
+ end
484
+
485
+ def self.run(yaml_hash: {})
486
+ failed = []
487
+ yaml_hash.each_with_index do |history, index|
488
+ failed += MonthHistory.new(index: index, yaml_hash: history).validate
489
+ failed += Annotation.new(index: index, yaml_hash: history).validate
490
+ failed += Reference.new(index: index, yaml_hash: history).validate
491
+ failed += Diffs.new(index: index, yaml_hash: history['diffs']).validate
492
+ end
493
+
494
+ failed
495
+ end
496
+ end
497
+ end
498
+ end