postman_paf 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/gem-push.yml +48 -0
  3. data/.github/workflows/gem-test.yml +22 -0
  4. data/.gitignore +17 -0
  5. data/.rspec +3 -0
  6. data/.rubocop.yml +36 -0
  7. data/CHANGELOG.md +5 -0
  8. data/CODE_OF_CONDUCT.md +84 -0
  9. data/Gemfile +6 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +174 -0
  12. data/Rakefile +12 -0
  13. data/bin/console +15 -0
  14. data/bin/setup +8 -0
  15. data/lib/postman_paf/converter.rb +65 -0
  16. data/lib/postman_paf/exceptions/exceptions.rb +29 -0
  17. data/lib/postman_paf/exceptions/last_part_exceptions.rb +36 -0
  18. data/lib/postman_paf/exceptions/rule_3_exceptions.rb +35 -0
  19. data/lib/postman_paf/exceptions/rule_5_and_7_exceptions.rb +24 -0
  20. data/lib/postman_paf/exceptions/rule_6_exceptions.rb +48 -0
  21. data/lib/postman_paf/exceptions/which_exception.rb +103 -0
  22. data/lib/postman_paf/printable_address.rb +35 -0
  23. data/lib/postman_paf/rules/address_builder.rb +30 -0
  24. data/lib/postman_paf/rules/building_number.rb +35 -0
  25. data/lib/postman_paf/rules/rule_1.rb +27 -0
  26. data/lib/postman_paf/rules/rule_2.rb +23 -0
  27. data/lib/postman_paf/rules/rule_3.rb +45 -0
  28. data/lib/postman_paf/rules/rule_4.rb +24 -0
  29. data/lib/postman_paf/rules/rule_5.rb +35 -0
  30. data/lib/postman_paf/rules/rule_6.rb +69 -0
  31. data/lib/postman_paf/rules/rule_7.rb +33 -0
  32. data/lib/postman_paf/rules/rules.rb +71 -0
  33. data/lib/postman_paf/rules/which_rule.rb +40 -0
  34. data/lib/postman_paf/validator.rb +65 -0
  35. data/lib/postman_paf/version.rb +5 -0
  36. data/lib/postman_paf.rb +32 -0
  37. data/postman_paf.gemspec +53 -0
  38. 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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PostmanPAF
4
+ VERSION = '0.3.0'
5
+ end
@@ -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
@@ -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: []