Module: GoingPostal

Extended by:
GoingPostal
Included in:
GoingPostal
Defined in:
lib/going_postal.rb

Constant Summary collapse

COUNTRIES_WITHOUT_POSTCODES =
Set[
  "AO", # Angola
  "AG", # Antigua and Barbuda
  "AN", # Netherlands Antilles
  "AW", # Aruba
  "BS", # Bahamas
  "BZ", # Belize
  "BJ", # Benin
  "BW", # Botswana
  "BF", # Burkina Faso
  "BI", # Burundi
  "CI", # Côte d’Ivoire
  "CD", # Congo, the Democratic Republic of the
  "CG", # Congo (Brazzaville)
  "CM", # Cameroon
  "CF", # Central African Republic
  "CW", # Curaçao
  "KM", # Comoros
  "CK", # Cook Islands
  "DJ", # Djibouti
  "DM", # Dominica
  "GQ", # Equatorial Guinea
  "ER", # Eritrea
  "FJ", # Fiji
  "GM", # Gambia
  "GH", # Ghana
  "GD", # Grenada
  "GN", # Guinea
  "GY", # Guyana
  "HK", # Hong Kong
  "IE", # Ireland
  "KI", # Kiribati
  "KP", # North Korea
  "MO", # Macau
  "MW", # Malawi
  "ML", # Mali
  "MR", # Mauritania
  "MU", # Mauritius
  "MS", # Montserrat
  "NA", # Namibia
  "NR", # Nauru
  "NU", # Niue
  "PA", # Panama
  "QA", # Qatar
  "RW", # Rwanda
  "KN", # Saint Kitts and Nevis
  "LC", # Saint Lucia
  "ST", # Sao Tome and Principe
  "SC", # Seychelles
  "SL", # Sierra Leone
  "SB", # Solomon Islands
  "SO", # Somalia
  "SR", # Suriname
  "SX", # Sint Maarten
  "SY", # Syria
  "TF", # French Southern and Antarctic Territories
  "TK", # Tokelau
  "TL", # East Timor
  "TO", # Tonga
  "TT", # Trinidad and Tobago
  "TV", # Tuvalu
  "TZ", # Tanzania
  "UG", # Uganda
  "AE", # United Arab Emirates
  "VU", # Vanuatu
  "YE", # Yemen
  "ZW"  # Zimbabwe
]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.not_required?(country_code) ⇒ Boolean

:call-seq: GoingPostal.not_required?(country_code) -> bool

Returns true if the country spcified by the two letter country code country_code argument does not require postcodes, false otherwise.

Returns:

  • (Boolean)


124
125
126
# File 'lib/going_postal.rb', line 124

def self.not_required?(country_code)
  COUNTRIES_WITHOUT_POSTCODES.include?(country_code.to_s.upcase)
end

.required?(country_code) ⇒ Boolean

:call-seq: GoingPostal.not_required?(country_code) -> bool

Returns true if the country spcified by the two letter country code country_code argument requires postcodes, false otherwise.

Returns:

  • (Boolean)


133
134
135
# File 'lib/going_postal.rb', line 133

def self.required?(country_code)
  !not_required?(country_code)
end

Instance Method Details

#format_au_postcode(string) ⇒ Object Also known as: format_nz_postcode, format_za_postcode



263
264
265
266
# File 'lib/going_postal.rb', line 263

def format_au_postcode(string)
  string = string.to_s.delete(" \t\r\n")
  string if string =~ /^[0-9]{4}$/
end

#format_ca_postcode(string) ⇒ Object



254
255
256
257
258
259
260
261
# File 'lib/going_postal.rb', line 254

def format_ca_postcode(string)
  forward_sort_area = string.to_s.upcase.delete(" \t\r\n")
  local_delivery_unit = forward_sort_area.slice!(-3, 3)
  if forward_sort_area =~ /^[A-CEGHJK-NPR-TVXY][0-9][A-CEGHJK-NPR-TV-Z]$/ &&
    local_delivery_unit =~ /[0-9][A-CEGHJK-NPR-TV-Z][0-9]/
    [forward_sort_area, local_delivery_unit].join(" ")
  end
end

#format_ch_postcode(string) ⇒ Object



280
281
282
283
# File 'lib/going_postal.rb', line 280

def format_ch_postcode(string)
  string = string.to_s.delete(" \t\r\n")
  string if string =~ /^[1-9][0-9]{3}$/
end

#format_gb_postcode(string) ⇒ Object Also known as: format_uk_postcode



244
245
246
247
248
249
250
251
# File 'lib/going_postal.rb', line 244

def format_gb_postcode(string)
  out_code = string.to_s.upcase.delete(" \t\r\n")
  in_code = out_code.slice!(-3, 3)
  if out_code =~ /^[A-Z]{1,2}([1-9][0-9A-HJKMNPR-Y]?|0[A-HJKMNPR-Y]?)$/ &&
    in_code =~ /^[0-9][A-HJLNP-Z]{2}$/
    [out_code, in_code].join(" ")
  end
end

#format_nl_postcode(string) ⇒ Object



285
286
287
288
289
# File 'lib/going_postal.rb', line 285

def format_nl_postcode(string)
  string = string.to_s.upcase.delete(" \t\r\n")
  string.insert(4, " ") if string.length >= 4
  string if string =~ /^[1-9][0-9]{3} (S[BCE-RT-Z]|[A-RT-Z][A-Z])$/
end

#format_non_postcode(string) ⇒ Object Also known as: format_ie_postcode

:stopdoc:



238
239
240
# File 'lib/going_postal.rb', line 238

def format_non_postcode(string)
  nil
end

#format_pl_postcode(string) ⇒ Object



291
292
293
294
# File 'lib/going_postal.rb', line 291

def format_pl_postcode(string)
  match = /^(\d\d)[^\w]*(\d\d\d)$/.match(string)
  match.captures.join("-") if match && match[1] && match[2]
end

#format_postcode(*args) ⇒ Object Also known as: format_post_code, format_zip, format_zipcode, format_zip_code

:call-seq: format_postcode([string[, country_code]]) -> formatted_str or nil

Returns a formatted postcode as a string if string is a valid postcode, nil otherwise.

If calling this method on the GoingPostal module the country_code argument is required and should be a two letter country code.

If the GoingPostal module has been mixed in to a class, and the class has a #country_code method, the country_code argument is optional, defaulting to the value returned by #country_code. If the class also has a #postcode, #post_code, #zipcode, #zip_code, or #zip method, the string argument becomes optional.

Postcodes for unknown countries will simply be stripped of leading and trailing whitespace.

Countries without postcodes will always return nil. – The magic is done calling a formatting method for each country. If no such method exists a default method is called stripping the leading and trailing whitespace. ++



222
223
224
225
226
227
228
229
230
# File 'lib/going_postal.rb', line 222

def format_postcode(*args)
  string, country_code = get_args_for_format_postcode(args)
  method = if GoingPostal.not_required?(country_code)
    :format_non_postcode
  else
    :"format_#{country_code.to_s.downcase}_postcode"
  end
  respond_to?(method) ? __send__(method, string) : string.to_s.strip
end

#format_us_zipcode(string) ⇒ Object Also known as: format_us_postcode



270
271
272
273
274
275
276
277
# File 'lib/going_postal.rb', line 270

def format_us_zipcode(string)
  zip = string.to_s.delete("- \t\r\n")
  plus_four = zip.slice!(5, 4)
  plus_four = nil if plus_four && plus_four.empty?
  if zip =~ /^[0-9]{5}$/ && (plus_four.nil? || plus_four =~ /^[0-9]{4}$/)
    [zip, plus_four].compact.join("-")
  end
end

#postcode?(*args) ⇒ Boolean Also known as: post_code?, zip?, zipcode?, zip_code?, valid_postcode?, valid_post_code?, valid_zip?, valid_zipcode?, valid_zip_code?, postcode_valid?, post_code_valid?, zip_valid?, zipcode_valid?, zip_code_valid?

:call-seq: postcode?([string[, country_code]]) -> formatted_str or false

Returns a formatted postcode as a string if string is a valid postcode, false otherwise.

If calling this method on the GoingPostal module the country_code argument is required and should be a two letter country code.

If the GoingPostal module has been mixed in to a class, and the class has a #country_code method, the country_code argument is optional, defaulting to the value returned by #country_code. If the class also has a #postcode, #post_code, #zipcode, #zip_code, or #zip method, the string argument becomes optional.

Postcodes for unknown countries will always be considered valid, the return value will consist of the input stripped of leading and trailing whitespace.

For countries without postcodes, “” will be returned from in input of “” or nil, false otherwise.

Returns:

  • (Boolean)


161
162
163
164
165
166
167
168
# File 'lib/going_postal.rb', line 161

def postcode?(*args)
  string, country_code = get_args_for_format_postcode(args)
  if GoingPostal.not_required?(country_code)
    string.nil? || string.to_s.empty? ? "" : false
  else
    format_postcode(string, country_code) || false
  end
end