zakuro 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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