lib/egn/generator.rb in egn-1.2.1 vs lib/egn/generator.rb in egn-1.2.2

- old
+ new

@@ -7,63 +7,97 @@ def self.generate(options={}) Generator.new(options).generate end def initialize(options={}) - @options = defaults.merge(options) - - validate!(@options) + validate!(options) + set_defaults!(options) + process! end # The generated EGN will be completely random if no opitons are given. # options is a hash that may have the following keys: :year, :month and :date def generate - randomize_options + # YY MM DD REST + egn = format(options[:year]) + format(options[:month]) + format(options[:day]) + format(options[:region], 3) - egn = options[:year].to_s.rjust(2, '0') + - options[:month].to_s.rjust(2, '0') + - options[:day].to_s.rjust(2,'0') + - options[:region].to_s.rjust(3,'0') + egn + Util.egn_checksum(egn).to_s + end - return egn + Util.egn_checksum(egn).to_s + private + + def set_defaults!(options) + @options = {} + + until Date.valid_date?(@options[:year].to_i, @options[:month].to_i, @options[:day].to_i) + @options = defaults.merge(options) + end + end + # Little helper + def format(val, pre=2) + val.to_s.rjust(pre, '0') + end + # Check if the options contain a date that is valid and be turned into an EGN def validate!(options) - raise ArgumentError, "Year out of bounds" unless (1800..2099).include?(options[:year]) - raise ArgumentError, "Month out of bounds" unless (1..12).include?(options[:month]) - raise ArgumentError, "Day out of bounds" unless (1..31).include?(options[:day]) - raise ArgumentError, "Invalid sex; valid values: [:male, :female]" unless [:male, :female].include?(options[:sex]) + raise ArgumentError, "Year out of bounds" if options[:year] && !(1800..2099).include?(options[:year]) + raise ArgumentError, "Month out of bounds" if options[:month] && !(1..12).include?(options[:month]) + raise ArgumentError, "Day out of bounds" if options[:day] && !(1..31).include?(options[:day]) + raise ArgumentError, "Sex should be one of #{sexes}" if options[:sex] && !sexes.include?(options[:sex]) end + # Random defaults def defaults - date = Util.time_rand + date = -> { Util.time_rand }.call { - year: date.year, - month: date.month, - day: date.day, - sex: [:male, :female].sample + year: date.year, + month: date.month, + day: date.day, + sex: sexes.sample, + region: Random.rand(0..999) } end - def randomize_options + def process! # Get random century, region and sex - options[:century] = options[:year] - (options[:year] % 100) - options[:region] = Random.rand(0..999) + century = determine_century(options[:year]) - # Recalculate month based on the century - options[:month] += 20 if options[:century] == 1800 - options[:month] += 40 if options[:century] == 2000 + options[:month] += month_delta(century) - # Recalculate region based on sex - if options[:sex] == :male && options[:region].odd? - options[:region] -= 1 - elsif options[:sex] == :female && options[:region].even? - options[:region] += 1 + options[:region] += region_delta(options[:sex], options[:region]) + + options[:year] = options[:year] - century + end + + # Recalculate region based on sex + def region_delta(sex, region) + if sex == :male && region.odd? + -1 + elsif sex == :female && region.even? + 1 + else + 0 end + end - options[:year] = options[:year] - options[:century] + def month_delta(century) + if century == 1800 + 20 + elsif century == 2000 + 40 + else + 0 + end end + def determine_century(year) + year - (year % 100) + end + + def sexes + [:male, :female] + end end end