postman_paf 0.3.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.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +48 -0
- data/.github/workflows/gem-test.yml +22 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.rubocop.yml +36 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +174 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/lib/postman_paf/converter.rb +65 -0
- data/lib/postman_paf/exceptions/exceptions.rb +29 -0
- data/lib/postman_paf/exceptions/last_part_exceptions.rb +36 -0
- data/lib/postman_paf/exceptions/rule_3_exceptions.rb +35 -0
- data/lib/postman_paf/exceptions/rule_5_and_7_exceptions.rb +24 -0
- data/lib/postman_paf/exceptions/rule_6_exceptions.rb +48 -0
- data/lib/postman_paf/exceptions/which_exception.rb +103 -0
- data/lib/postman_paf/printable_address.rb +35 -0
- data/lib/postman_paf/rules/address_builder.rb +30 -0
- data/lib/postman_paf/rules/building_number.rb +35 -0
- data/lib/postman_paf/rules/rule_1.rb +27 -0
- data/lib/postman_paf/rules/rule_2.rb +23 -0
- data/lib/postman_paf/rules/rule_3.rb +45 -0
- data/lib/postman_paf/rules/rule_4.rb +24 -0
- data/lib/postman_paf/rules/rule_5.rb +35 -0
- data/lib/postman_paf/rules/rule_6.rb +69 -0
- data/lib/postman_paf/rules/rule_7.rb +33 -0
- data/lib/postman_paf/rules/rules.rb +71 -0
- data/lib/postman_paf/rules/which_rule.rb +40 -0
- data/lib/postman_paf/validator.rb +65 -0
- data/lib/postman_paf/version.rb +5 -0
- data/lib/postman_paf.rb +32 -0
- data/postman_paf.gemspec +53 -0
- metadata +210 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PostmanPAF
|
4
|
+
# Validator class for user input. Verifies input contains required PAF
|
5
|
+
# address elements for mailing.
|
6
|
+
# @see https://www.poweredbypaf.com/wp-content/uploads/2017/07/Latest-Programmers_guide_Edition-7-Version-6.pdf Page 12
|
7
|
+
class Validator
|
8
|
+
POST_TOWN = 'postTown'
|
9
|
+
POSTCODE = 'postcode'
|
10
|
+
|
11
|
+
# @param input the object to be validated.
|
12
|
+
# @return Validator object.
|
13
|
+
def initialize(input:)
|
14
|
+
@input = input
|
15
|
+
end
|
16
|
+
|
17
|
+
# Verifies input meets minimum requirements for address conversion.
|
18
|
+
# @raise [ArgumentError] if input is not a Hash or Array.
|
19
|
+
# @return [nil] if Hash or Array meet address conversion
|
20
|
+
# requirements.
|
21
|
+
def validate
|
22
|
+
if @input.is_a?(Hash)
|
23
|
+
validate_single_address
|
24
|
+
elsif @input.is_a?(Array) && @input.size.positive?
|
25
|
+
validate_multiple_addresses
|
26
|
+
else
|
27
|
+
raise ArgumentError, 'Conversion input must be either a hash containing data for an address, or an array of hashes each containing data for an address'
|
28
|
+
end
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Verifies input of single Hash contains required address elements.
|
35
|
+
# @raise [ArgumentError] if Hash is missing required address elements.
|
36
|
+
# @return [nil] if Hash contains required address elements.
|
37
|
+
def validate_single_address
|
38
|
+
raise ArgumentError, "Hash of address data must contain 'postTown' and 'postcode' keys" unless criteria_for_paf_address?(hash: @input)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Verifies input of Array contains a Hash as each element and that
|
42
|
+
# each Hash contains required address elements.
|
43
|
+
# @raise [ArgumentError] if an Array elements is not a Hash.
|
44
|
+
# @raise [ArgumentError] if Hash element is missing required
|
45
|
+
# address elements.
|
46
|
+
# @return [nil] if each Array element is a Hash which contains
|
47
|
+
# required PAF address elements.
|
48
|
+
def validate_multiple_addresses
|
49
|
+
@input.each do |element|
|
50
|
+
raise ArgumentError, 'Each address element in the array must be a hash' unless element.is_a?(Hash)
|
51
|
+
|
52
|
+
raise ArgumentError, "Hash of address data must contain 'postTown' and 'postcode' keys" unless criteria_for_paf_address?(hash: element)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Checks if postTown and postcode keys exist within a Hash
|
57
|
+
# (Ruby or JSON Hash syntax).
|
58
|
+
# @param hash [Hash] the Hash object.
|
59
|
+
# @return [Boolean] whether both keys were found.
|
60
|
+
def criteria_for_paf_address?(hash:)
|
61
|
+
hash = hash.transform_keys { |k| SimpleSymbolize.camelize(k).to_s }
|
62
|
+
hash.keys.include?(POST_TOWN) && hash.keys.include?(POSTCODE)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/postman_paf.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
require 'simple_symbolize'
|
6
|
+
|
7
|
+
Dir['./lib/postman_paf/**/*.rb'].each do |file|
|
8
|
+
require file
|
9
|
+
end
|
10
|
+
|
11
|
+
module PostmanPAF
|
12
|
+
# Initialise Logger output.
|
13
|
+
LOG = Logger.new($stdout)
|
14
|
+
LOG.formatter = proc { |severity, datetime, _progname, msg| "[#{datetime} #{severity} PostmanPAF] -- #{msg}\n" }
|
15
|
+
|
16
|
+
# Converts PAF address data to printable format based on Royal Mail
|
17
|
+
# rules and exceptions.
|
18
|
+
# @see https://www.poweredbypaf.com/wp-content/uploads/2017/07/Latest-Programmers_guide_Edition-7-Version-6.pdf
|
19
|
+
# @param input [Hash, Array<Hash>] PAF address data.
|
20
|
+
# @param max_line_length [Integer, String] optional argument to set
|
21
|
+
# max length of printable address lines 1-5.
|
22
|
+
# @param logging [Boolean] optional argument to log rule and
|
23
|
+
# exception(s) applied during conversion.
|
24
|
+
# @raises [ArgumentError] if invalid input given.
|
25
|
+
# @return [Hash, Array<Hash>, nil] converted address data, nil if
|
26
|
+
# conversion data ineligible for conversion.
|
27
|
+
def self.convert(input, max_line_length: nil, logging: false)
|
28
|
+
Validator.new(input: input).validate
|
29
|
+
|
30
|
+
Converter.new(paf_address_data: input, max_line_length: max_line_length, logging: logging).convert
|
31
|
+
end
|
32
|
+
end
|
data/postman_paf.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/postman_paf/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'postman_paf'
|
7
|
+
spec.version = PostmanPAF::VERSION
|
8
|
+
spec.authors = ['Driver and Vehicle Licensing Agency (DVLA)', 'Mark Isaac']
|
9
|
+
spec.email = ['mark.isaac@dvla.gov.uk']
|
10
|
+
|
11
|
+
spec.summary = 'Convert PAF (Postcode Address File) addresses to a printable format for an envelope or address label.'
|
12
|
+
|
13
|
+
spec.description = <<-DESCRIPTION
|
14
|
+
Unofficial gem to apply Royal Mail Rules & Exceptions to PAF (Postcode Address File) addresses when converting to a printable format. Based on the Royal Mail Programmers' Guide:
|
15
|
+
https://www.poweredbypaf.com/wp-content/uploads/2017/07/Latest-Programmers_guide_Edition-7-Version-6.pdf,'Formatting a PAF address for printing' (page 27). Addresses conversions
|
16
|
+
aim to resemble addresses returned by Royal Mail Find a PostCode as accurately as possible: https://www.royalmail.com/find-a-postcode.
|
17
|
+
DESCRIPTION
|
18
|
+
|
19
|
+
# spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
20
|
+
spec.license = 'MIT'
|
21
|
+
spec.required_ruby_version = '>= 3.0'
|
22
|
+
|
23
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'https://mygemserver.com'"
|
24
|
+
|
25
|
+
# spec.metadata['homepage_uri'] = spec.homepage
|
26
|
+
# spec.metadata['source_code_uri'] = "TODO: Put your gem's public repo URL here."
|
27
|
+
# spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
|
28
|
+
|
29
|
+
# Specify which files should be added to the gem when it is released.
|
30
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
31
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
33
|
+
end
|
34
|
+
spec.bindir = 'exe'
|
35
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
36
|
+
spec.require_paths = ['lib']
|
37
|
+
|
38
|
+
# Uncomment to register a new dependency of your gem
|
39
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
40
|
+
|
41
|
+
# For more information and examples about making a new gem, checkout our
|
42
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
43
|
+
spec.add_development_dependency 'bundler-audit', '~> 0.9'
|
44
|
+
spec.add_development_dependency 'hash_miner', '~> 1.1'
|
45
|
+
spec.add_development_dependency 'pry', '~> 0.14'
|
46
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
47
|
+
spec.add_development_dependency 'rspec', '~> 3.12'
|
48
|
+
spec.add_development_dependency 'rubocop', '~> 1.54'
|
49
|
+
spec.add_development_dependency 'simplecov', '~> 0.22'
|
50
|
+
spec.add_development_dependency 'simplecov-console', '~> 0.9'
|
51
|
+
|
52
|
+
spec.add_runtime_dependency 'simple_symbolize', '~> 4.0'
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: postman_paf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Driver and Vehicle Licensing Agency (DVLA)
|
8
|
+
- Mark Isaac
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2024-02-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler-audit
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.9'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.9'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: hash_miner
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.1'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.1'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: pry
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0.14'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.14'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rake
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '13.0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '13.0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '3.12'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '3.12'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rubocop
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '1.54'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '1.54'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: simplecov
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0.22'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0.22'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: simplecov-console
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0.9'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0.9'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: simple_symbolize
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - "~>"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '4.0'
|
133
|
+
type: :runtime
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '4.0'
|
140
|
+
description: |2
|
141
|
+
Unofficial gem to apply Royal Mail Rules & Exceptions to PAF (Postcode Address File) addresses when converting to a printable format. Based on the Royal Mail Programmers' Guide:
|
142
|
+
https://www.poweredbypaf.com/wp-content/uploads/2017/07/Latest-Programmers_guide_Edition-7-Version-6.pdf,'Formatting a PAF address for printing' (page 27). Addresses conversions
|
143
|
+
aim to resemble addresses returned by Royal Mail Find a PostCode as accurately as possible: https://www.royalmail.com/find-a-postcode.
|
144
|
+
email:
|
145
|
+
- mark.isaac@dvla.gov.uk
|
146
|
+
executables: []
|
147
|
+
extensions: []
|
148
|
+
extra_rdoc_files: []
|
149
|
+
files:
|
150
|
+
- ".github/workflows/gem-push.yml"
|
151
|
+
- ".github/workflows/gem-test.yml"
|
152
|
+
- ".gitignore"
|
153
|
+
- ".rspec"
|
154
|
+
- ".rubocop.yml"
|
155
|
+
- CHANGELOG.md
|
156
|
+
- CODE_OF_CONDUCT.md
|
157
|
+
- Gemfile
|
158
|
+
- LICENSE.txt
|
159
|
+
- README.md
|
160
|
+
- Rakefile
|
161
|
+
- bin/console
|
162
|
+
- bin/setup
|
163
|
+
- lib/postman_paf.rb
|
164
|
+
- lib/postman_paf/converter.rb
|
165
|
+
- lib/postman_paf/exceptions/exceptions.rb
|
166
|
+
- lib/postman_paf/exceptions/last_part_exceptions.rb
|
167
|
+
- lib/postman_paf/exceptions/rule_3_exceptions.rb
|
168
|
+
- lib/postman_paf/exceptions/rule_5_and_7_exceptions.rb
|
169
|
+
- lib/postman_paf/exceptions/rule_6_exceptions.rb
|
170
|
+
- lib/postman_paf/exceptions/which_exception.rb
|
171
|
+
- lib/postman_paf/printable_address.rb
|
172
|
+
- lib/postman_paf/rules/address_builder.rb
|
173
|
+
- lib/postman_paf/rules/building_number.rb
|
174
|
+
- lib/postman_paf/rules/rule_1.rb
|
175
|
+
- lib/postman_paf/rules/rule_2.rb
|
176
|
+
- lib/postman_paf/rules/rule_3.rb
|
177
|
+
- lib/postman_paf/rules/rule_4.rb
|
178
|
+
- lib/postman_paf/rules/rule_5.rb
|
179
|
+
- lib/postman_paf/rules/rule_6.rb
|
180
|
+
- lib/postman_paf/rules/rule_7.rb
|
181
|
+
- lib/postman_paf/rules/rules.rb
|
182
|
+
- lib/postman_paf/rules/which_rule.rb
|
183
|
+
- lib/postman_paf/validator.rb
|
184
|
+
- lib/postman_paf/version.rb
|
185
|
+
- postman_paf.gemspec
|
186
|
+
homepage:
|
187
|
+
licenses:
|
188
|
+
- MIT
|
189
|
+
metadata: {}
|
190
|
+
post_install_message:
|
191
|
+
rdoc_options: []
|
192
|
+
require_paths:
|
193
|
+
- lib
|
194
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
195
|
+
requirements:
|
196
|
+
- - ">="
|
197
|
+
- !ruby/object:Gem::Version
|
198
|
+
version: '3.0'
|
199
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '0'
|
204
|
+
requirements: []
|
205
|
+
rubygems_version: 3.3.7
|
206
|
+
signing_key:
|
207
|
+
specification_version: 4
|
208
|
+
summary: Convert PAF (Postcode Address File) addresses to a printable format for an
|
209
|
+
envelope or address label.
|
210
|
+
test_files: []
|