USPS-intelligent-barcode 0.2.2 → 0.2.3
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.
- data/Gemfile +2 -1
- data/Gemfile.lock +2 -0
- data/Rakefile +3 -9
- data/USPS-intelligent-barcode.gemspec +9 -6
- data/VERSION +1 -1
- data/lib/USPS-intelligent-barcode/BarMap.rb +4 -4
- data/lib/USPS-intelligent-barcode/BarPosition.rb +8 -5
- data/lib/USPS-intelligent-barcode/Barcode.rb +24 -24
- data/lib/USPS-intelligent-barcode/BarcodeId.rb +29 -19
- data/lib/USPS-intelligent-barcode/CharacterPosition.rb +7 -2
- data/lib/USPS-intelligent-barcode/CodewordMap.rb +5 -2
- data/lib/USPS-intelligent-barcode/Crc.rb +6 -3
- data/lib/USPS-intelligent-barcode/MailerId.rb +28 -19
- data/lib/USPS-intelligent-barcode/NumericConversions.rb +7 -2
- data/lib/USPS-intelligent-barcode/RoutingCode.rb +40 -31
- data/lib/USPS-intelligent-barcode/SerialNumber.rb +27 -18
- data/lib/USPS-intelligent-barcode/ServiceType.rb +26 -18
- metadata +111 -64
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -20,7 +20,7 @@ Jeweler::Tasks.new do |gem|
|
|
20
20
|
gem.license = "MIT"
|
21
21
|
gem.summary = %Q{Generates a USPS Intelligent Mail Barcode.}
|
22
22
|
gem.description =
|
23
|
-
("A pure Ruby
|
23
|
+
("A pure Ruby library to generate a USPS Intelligent "\
|
24
24
|
"Mail barcode. It generates the string of characters "\
|
25
25
|
"to print with one of the USPS Intelligent Mail barcode "\
|
26
26
|
"fonts.")
|
@@ -35,12 +35,6 @@ RSpec::Core::RakeTask.new(:spec)
|
|
35
35
|
|
36
36
|
task :default => :spec
|
37
37
|
|
38
|
-
require '
|
39
|
-
Rake::
|
40
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
-
|
42
|
-
rdoc.rdoc_dir = 'rdoc'
|
43
|
-
rdoc.title = "USPS-intelligent-barcode #{version}"
|
44
|
-
rdoc.rdoc_files.include('README*')
|
45
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
38
|
+
require 'yard'
|
39
|
+
YARD::Rake::YardocTask.new do |t|
|
46
40
|
end
|
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "USPS-intelligent-barcode"
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Wayne Conrad"]
|
12
|
-
s.date = "2012-12-
|
13
|
-
s.description = "A pure Ruby
|
12
|
+
s.date = "2012-12-31"
|
13
|
+
s.description = "A pure Ruby library to generate a USPS Intelligent Mail barcode. It generates the string of characters to print with one of the USPS Intelligent Mail barcode fonts."
|
14
14
|
s.email = "wayne@databill.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.md",
|
@@ -66,22 +66,25 @@ Gem::Specification.new do |s|
|
|
66
66
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
67
67
|
s.add_runtime_dependency(%q<andand>, ["~> 1.3"])
|
68
68
|
s.add_runtime_dependency(%q<memoizer>, ["~> 1.0"])
|
69
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.12"])
|
70
69
|
s.add_development_dependency(%q<jeweler>, ["~> 1.8"])
|
70
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.12"])
|
71
71
|
s.add_development_dependency(%q<simplecov>, ["~> 0.7"])
|
72
|
+
s.add_development_dependency(%q<yard>, ["~> 0.8"])
|
72
73
|
else
|
73
74
|
s.add_dependency(%q<andand>, ["~> 1.3"])
|
74
75
|
s.add_dependency(%q<memoizer>, ["~> 1.0"])
|
75
|
-
s.add_dependency(%q<rspec>, ["~> 2.12"])
|
76
76
|
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
77
|
+
s.add_dependency(%q<rspec>, ["~> 2.12"])
|
77
78
|
s.add_dependency(%q<simplecov>, ["~> 0.7"])
|
79
|
+
s.add_dependency(%q<yard>, ["~> 0.8"])
|
78
80
|
end
|
79
81
|
else
|
80
82
|
s.add_dependency(%q<andand>, ["~> 1.3"])
|
81
83
|
s.add_dependency(%q<memoizer>, ["~> 1.0"])
|
82
|
-
s.add_dependency(%q<rspec>, ["~> 2.12"])
|
83
84
|
s.add_dependency(%q<jeweler>, ["~> 1.8"])
|
85
|
+
s.add_dependency(%q<rspec>, ["~> 2.12"])
|
84
86
|
s.add_dependency(%q<simplecov>, ["~> 0.7"])
|
87
|
+
s.add_dependency(%q<yard>, ["~> 0.8"])
|
85
88
|
end
|
86
89
|
end
|
87
90
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
@@ -1,15 +1,14 @@
|
|
1
1
|
require 'USPS-intelligent-barcode/CharacterPosition'
|
2
2
|
|
3
|
+
# @!group Internal
|
4
|
+
|
3
5
|
module Imb
|
4
6
|
|
5
7
|
# Maps intelligent barcode "characters" to codes that indicate what
|
6
|
-
# type of bar to print at each given position.
|
7
|
-
# internal and may change.
|
8
|
+
# type of bar to print at each given position.
|
8
9
|
|
9
10
|
class BarMap
|
10
11
|
|
11
|
-
# Create.
|
12
|
-
|
13
12
|
def initialize
|
14
13
|
@mapping = load_mapping
|
15
14
|
end
|
@@ -20,6 +19,7 @@ module Imb
|
|
20
19
|
# * 1 - descending mark
|
21
20
|
# * 2 - ascending mark
|
22
21
|
# * 3 - full mark (both ascending and descending)
|
22
|
+
# @return [[Integer]]
|
23
23
|
|
24
24
|
def barcode(characters)
|
25
25
|
@mapping.map do |bar_position|
|
@@ -1,25 +1,28 @@
|
|
1
1
|
module Imb
|
2
2
|
|
3
|
+
# @!group Internal
|
4
|
+
|
3
5
|
# Represents a position (one line) in the barcode. This class is
|
4
6
|
# internal and may change.
|
5
7
|
|
6
8
|
class BarPosition
|
7
9
|
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# * +ascender_character_position* - the CharacterPosition for the ascender
|
10
|
+
# @param [CharacterPosition] descender_character_position
|
11
|
+
# @param [CharacterPosition] ascender_character_position
|
11
12
|
|
12
13
|
def initialize(descender_character_position, ascender_character_position)
|
13
14
|
@descender_character_position = descender_character_position
|
14
15
|
@ascender_character_position = ascender_character_position
|
15
16
|
end
|
16
17
|
|
17
|
-
# Given an array of characters, return a code for this
|
18
|
-
# position. The codes are:
|
18
|
+
# Given an array of characters, return a symbol code for this
|
19
|
+
# barcode position. The symbol codes are:
|
19
20
|
# * 0 - tracking mark (neither ascending nor descending)
|
20
21
|
# * 1 - descending mark
|
21
22
|
# * 2 - ascending mark
|
22
23
|
# * 3 - full mark (both ascending and descending)
|
24
|
+
# @param [[Integer]] characters character codes
|
25
|
+
# @return [Integer] symbol code
|
23
26
|
|
24
27
|
def map(characters)
|
25
28
|
2 * ascender_bit(characters) + descender_bit(characters)
|
@@ -1,43 +1,44 @@
|
|
1
1
|
require 'USPS-intelligent-barcode/CodewordMap'
|
2
2
|
|
3
|
-
# The namespace for everything in this
|
3
|
+
# The namespace for everything in this library.
|
4
4
|
|
5
5
|
module Imb
|
6
6
|
|
7
|
-
# This class represents a barcode.
|
8
|
-
# probably seldom need to touch any of the others.
|
7
|
+
# This class represents a barcode.
|
9
8
|
|
10
9
|
class Barcode
|
11
10
|
|
12
11
|
include Memoizer
|
13
12
|
|
14
|
-
#
|
13
|
+
# @return [BarcodeId]
|
15
14
|
attr_reader :barcode_id
|
16
15
|
|
17
|
-
#
|
16
|
+
# @return [ServiceType]
|
18
17
|
attr_reader :service_type
|
19
18
|
|
20
|
-
#
|
19
|
+
# @return [MailerId]
|
21
20
|
attr_reader :mailer_id
|
22
21
|
|
23
|
-
#
|
22
|
+
# @return [SerialNumber]
|
24
23
|
attr_reader :serial_number
|
25
24
|
|
26
|
-
#
|
25
|
+
# @return [RoutingCode]
|
27
26
|
attr_reader :routing_code
|
28
27
|
|
29
|
-
#
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
28
|
+
# @param
|
29
|
+
|
30
|
+
# Create a new barcode
|
31
|
+
#
|
32
|
+
# @param barcode_id [String] Nominally a String, but can be
|
33
|
+
# anything that {BarcodeId.coerce} will accept.
|
34
|
+
# @param service_type [String] Nominally a String, but can be
|
35
|
+
# anything that {ServiceType.coerce} will accept.
|
36
|
+
# @param mailer_id [String] Nominally a String, but can be
|
37
|
+
# anything that {MailerId.coerce} will accept.
|
38
|
+
# @param serial_number [String] Nominally a String, but can be
|
39
|
+
# anything that {SerialNumber.coerce} will accept.
|
40
|
+
# @param routing_code [String] Nominally a String, but can be
|
41
|
+
# anything that {RoutingCode.coerce} will accept.
|
41
42
|
|
42
43
|
def initialize(barcode_id,
|
43
44
|
service_type,
|
@@ -52,14 +53,13 @@ module Imb
|
|
52
53
|
validate_components
|
53
54
|
end
|
54
55
|
|
55
|
-
# Return a string
|
56
|
-
# the string will be one of:
|
56
|
+
# Return a string to print using one of the USPS Intelligent Mail
|
57
|
+
# Barcode fonts. Each character of the string will be one of:
|
57
58
|
# * 'T' for a tracking mark (neither ascender nor descender)
|
58
59
|
# * 'A' for an ascender mark
|
59
60
|
# * 'D' for a descender mark
|
60
61
|
# * 'F' for a full mark (both ascender and descender)
|
61
|
-
#
|
62
|
-
# Intelligent Mail Barcode fonts
|
62
|
+
# @return [String] A string that represents the barcode.
|
63
63
|
|
64
64
|
def barcode_letters
|
65
65
|
barcode.map { |bar| "TDAF"[bar..bar] }.join
|
@@ -10,10 +10,12 @@ module Imb
|
|
10
10
|
# The allowable range of a barcode ID's least significant digit
|
11
11
|
LSD_RANGE = 0..4
|
12
12
|
|
13
|
-
# Turn the argument into a BarcodeID if possible. Accepts:
|
14
|
-
# * BarcodeId
|
13
|
+
# Turn the argument into a BarcodeID if possible. Accepts any of:
|
14
|
+
# * {BarcodeId}
|
15
15
|
# * String
|
16
16
|
# * Integer
|
17
|
+
# @return [BarcodeId]
|
18
|
+
# @raise [ArgumentError] If the argument cannot be coerced
|
17
19
|
|
18
20
|
def self.coerce(o)
|
19
21
|
case o
|
@@ -29,14 +31,32 @@ module Imb
|
|
29
31
|
end
|
30
32
|
|
31
33
|
# Create a new BarcodeId
|
32
|
-
#
|
34
|
+
# @param [Integer] value The barcode ID
|
33
35
|
|
34
36
|
def initialize(value)
|
35
37
|
@value = value
|
36
38
|
end
|
37
39
|
|
38
|
-
#
|
39
|
-
#
|
40
|
+
# Return true if this object is equal to o
|
41
|
+
# @param [Object] o Any object acceptable to {.coerce}
|
42
|
+
|
43
|
+
def ==(o)
|
44
|
+
BarcodeId.coerce(o).to_i == to_i
|
45
|
+
rescue ArgumentError
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Integer] The integer value of the barcode ID
|
50
|
+
|
51
|
+
def to_i
|
52
|
+
@value
|
53
|
+
end
|
54
|
+
|
55
|
+
# @!group Internal
|
56
|
+
|
57
|
+
# Validate the value.
|
58
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
59
|
+
# @raise ArgumentError if invalid
|
40
60
|
|
41
61
|
def validate(long_mailer_id)
|
42
62
|
unless RANGE === @value
|
@@ -47,17 +67,11 @@ module Imb
|
|
47
67
|
end
|
48
68
|
end
|
49
69
|
|
50
|
-
# Return true if +o+ is equal. +o+ may be any object which ::coerce
|
51
|
-
# can turn into a BarcodeId.
|
52
|
-
|
53
|
-
def ==(o)
|
54
|
-
BarcodeId.coerce(o).to_i == to_i
|
55
|
-
rescue ArgumentError
|
56
|
-
false
|
57
|
-
end
|
58
|
-
|
59
70
|
# Add this object's value to target, shifting it left as many
|
60
71
|
# digts as are needed to make room.
|
72
|
+
# @param [Integer] target The target to be shifted and added to
|
73
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
74
|
+
# @return [Integer] The new value of the target
|
61
75
|
|
62
76
|
def shift_and_add_to(target, long_mailer_id)
|
63
77
|
target *= 10
|
@@ -67,11 +81,7 @@ module Imb
|
|
67
81
|
target
|
68
82
|
end
|
69
83
|
|
70
|
-
#
|
71
|
-
|
72
|
-
def to_i
|
73
|
-
@value
|
74
|
-
end
|
84
|
+
# @!endgroup
|
75
85
|
|
76
86
|
private
|
77
87
|
|
@@ -1,11 +1,14 @@
|
|
1
1
|
module Imb
|
2
2
|
|
3
|
+
# @!group Internal
|
4
|
+
|
3
5
|
# Represents the position of one bit in the array of intelligent
|
4
|
-
# barcode "characters".
|
6
|
+
# barcode "characters".
|
5
7
|
|
6
8
|
class CharacterPosition
|
7
9
|
|
8
|
-
#
|
10
|
+
# @param [Integer] character_index
|
11
|
+
# @param [Integer] bit_number
|
9
12
|
|
10
13
|
def initialize(character_index, bit_number)
|
11
14
|
@character_index = character_index
|
@@ -13,6 +16,8 @@ module Imb
|
|
13
16
|
end
|
14
17
|
|
15
18
|
# Given an array of characters, return the bit for this position.
|
19
|
+
# @param [[Integer]] characters
|
20
|
+
# @return [Integer] bit (0 or 1)
|
16
21
|
|
17
22
|
def extract_bit_from_characters(characters)
|
18
23
|
characters[@character_index][@bit_number]
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Imb
|
2
2
|
|
3
|
-
#
|
4
|
-
|
3
|
+
# @!group Internal
|
4
|
+
|
5
|
+
# Maps codewords to characters.
|
5
6
|
|
6
7
|
class CodewordMap
|
7
8
|
|
@@ -12,6 +13,8 @@ module Imb
|
|
12
13
|
end
|
13
14
|
|
14
15
|
# Given an array of codewords, ruturn their characters.
|
16
|
+
# @param [[Integer]] codewords
|
17
|
+
# @return [[Integer]] Array of characters
|
15
18
|
|
16
19
|
def characters(codewords)
|
17
20
|
codewords.map do |codeword|
|
@@ -2,14 +2,17 @@ require 'USPS-intelligent-barcode/NumericConversions'
|
|
2
2
|
|
3
3
|
module Imb
|
4
4
|
|
5
|
-
#
|
6
|
-
|
5
|
+
# @!group Internal
|
6
|
+
|
7
|
+
# Calculates the Intelligent Mail Barcode CRC.
|
7
8
|
|
8
9
|
class Crc
|
9
10
|
|
10
11
|
extend NumericConversions
|
11
12
|
|
12
|
-
# Calculate a CRC.
|
13
|
+
# Calculate a CRC.
|
14
|
+
# @param [Integer] binary_data A 102-bit integer
|
15
|
+
# @return [Integer] An 11-bit CRC
|
13
16
|
|
14
17
|
def self.crc(binary_data)
|
15
18
|
crc = MASK
|
@@ -14,9 +14,11 @@ module Imb
|
|
14
14
|
RANGES = [SHORT_RANGE, LONG_RANGE]
|
15
15
|
|
16
16
|
# Turn the argument into a MailerID if possible. Accepts:
|
17
|
-
# * MailerId
|
17
|
+
# * {MailerId}
|
18
18
|
# * String
|
19
19
|
# * Integer
|
20
|
+
# @return [MailerId]
|
21
|
+
# @raise [ArgumentError] If the argument cannot be coerced
|
20
22
|
|
21
23
|
def self.coerce(o)
|
22
24
|
case o
|
@@ -31,24 +33,14 @@ module Imb
|
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
|
-
#
|
35
|
-
# * +value+ - The integer value of the MailerId
|
36
|
+
# @param [Integer] value
|
36
37
|
|
37
38
|
def initialize(value)
|
38
39
|
@value = value
|
39
40
|
end
|
40
41
|
|
41
|
-
#
|
42
|
-
#
|
43
|
-
|
44
|
-
def validate(long_mailer_id)
|
45
|
-
unless in_range?
|
46
|
-
raise ArgumentError, "Must be #{RANGES.join(' or ')}"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Return true if +o+ is equal. +o+ may be any object which ::coerce
|
51
|
-
# can turn into a MailerId.
|
42
|
+
# Return true if this object is equal to o
|
43
|
+
# @param [Object] o Any object acceptable to {.coerce}
|
52
44
|
|
53
45
|
def ==(o)
|
54
46
|
MailerId.coerce(o).to_i == to_i
|
@@ -56,24 +48,41 @@ module Imb
|
|
56
48
|
false
|
57
49
|
end
|
58
50
|
|
51
|
+
# @return [Integer] The value of the mailer ID
|
52
|
+
|
53
|
+
def to_i
|
54
|
+
@value
|
55
|
+
end
|
56
|
+
|
57
|
+
# @!group Internal
|
58
|
+
|
59
59
|
# Return true if this is a long (9 digit) mailer ID
|
60
60
|
|
61
61
|
def long?
|
62
62
|
LONG_RANGE === @value
|
63
63
|
end
|
64
|
+
|
65
|
+
# Validate the value.
|
66
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
67
|
+
# @raise ArgumentError if invalid
|
68
|
+
|
69
|
+
def validate(long_mailer_id)
|
70
|
+
unless in_range?
|
71
|
+
raise ArgumentError, "Must be #{RANGES.join(' or ')}"
|
72
|
+
end
|
73
|
+
end
|
64
74
|
|
65
75
|
# Add this object's value to target, shifting it left as many
|
66
76
|
# digts as are needed to make room.
|
77
|
+
# @param [Integer] target The target to be shifted and added to
|
78
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
79
|
+
# @return [Integer] The new value of the target
|
67
80
|
|
68
81
|
def shift_and_add_to(target, long_mailer_id)
|
69
82
|
target * 10 ** num_digits + to_i
|
70
83
|
end
|
71
84
|
|
72
|
-
#
|
73
|
-
|
74
|
-
def to_i
|
75
|
-
@value
|
76
|
-
end
|
85
|
+
# @!endgroup
|
77
86
|
|
78
87
|
private
|
79
88
|
|
@@ -1,10 +1,15 @@
|
|
1
1
|
module Imb
|
2
2
|
|
3
|
-
#
|
3
|
+
# @!group Internal
|
4
|
+
|
5
|
+
# Numeric conversions
|
4
6
|
|
5
7
|
module NumericConversions
|
6
8
|
|
7
|
-
# Convert a
|
9
|
+
# Convert a numeric to an array of at least +min_bytes+ bytes.
|
10
|
+
# @param [Numeric] n
|
11
|
+
# @param [Integer] min_bytes
|
12
|
+
# @return [[Integer]] Array of bytes
|
8
13
|
|
9
14
|
def numeric_to_bytes(n, min_bytes=0)
|
10
15
|
n.to_s(16).rjust(2 * min_bytes, '0').scan(/../).map do |s|
|
@@ -5,7 +5,7 @@ module Imb
|
|
5
5
|
class RoutingCode
|
6
6
|
|
7
7
|
# Turn the argument into a RoutingCode if possible. Accepts:
|
8
|
-
# * RoutingCode
|
8
|
+
# * {RoutingCode}
|
9
9
|
# * nil (no routing code)
|
10
10
|
# * String of length:
|
11
11
|
# * 0 - no routing code
|
@@ -13,6 +13,7 @@ module Imb
|
|
13
13
|
# * 9 - zip + plus4
|
14
14
|
# * 11 - zip + plus4 + delivery point
|
15
15
|
# * Array of [zip, plus4, delivery point]
|
16
|
+
# @return [RoutingCode]
|
16
17
|
|
17
18
|
def self.coerce(o)
|
18
19
|
case o
|
@@ -29,32 +30,13 @@ module Imb
|
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
|
-
#
|
33
|
-
# an array that can be passed to the constructor.
|
34
|
-
# +s+ is a string of length:
|
35
|
-
# * 0 - no routing code
|
36
|
-
# * 5 - zip
|
37
|
-
# * 9 - zip + plus4
|
38
|
-
# * 11 - zip + plus4 + delivery point
|
39
|
-
# The result is an array of [zip, zip4, delivery point]
|
40
|
-
|
41
|
-
def self.string_to_array(s)
|
42
|
-
s = s.gsub(/[\D]/, '')
|
43
|
-
match = /^(?:(\d{5})(?:(\d{4})(\d{2})?)?)?$/.match(s)
|
44
|
-
unless match
|
45
|
-
raise ArgumentError, "Bad routing code: #{s.inspect}"
|
46
|
-
end
|
47
|
-
zip, plus4, delivery_point = match.to_a[1..-1]
|
48
|
-
[zip, plus4, delivery_point]
|
49
|
-
end
|
50
|
-
|
51
|
-
# Return the ZIP (or nil)
|
33
|
+
# @return [Integer] The ZIP (or nil)
|
52
34
|
attr_accessor :zip
|
53
35
|
|
54
|
-
#
|
36
|
+
# @return [Integer] The plus4 (or nil)
|
55
37
|
attr_accessor :plus4
|
56
38
|
|
57
|
-
#
|
39
|
+
# @return [Integer] The delivery point (or nil)
|
58
40
|
attr_accessor :delivery_point
|
59
41
|
|
60
42
|
# Create a RoutingCode. Arguments are:
|
@@ -68,14 +50,8 @@ module Imb
|
|
68
50
|
@delivery_point = arg_to_i(delivery_point)
|
69
51
|
end
|
70
52
|
|
71
|
-
#
|
72
|
-
#
|
73
|
-
|
74
|
-
def validate(long_mailer_id)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Return true if +o+ is equal. +o+ may be any object which ::coerce
|
78
|
-
# can turn into a RoutingCode.
|
53
|
+
# Return true if this object is equal to o
|
54
|
+
# @param [Object] o Any object acceptable to {.coerce}
|
79
55
|
|
80
56
|
def ==(o)
|
81
57
|
RoutingCode.coerce(o).to_a == to_a
|
@@ -83,13 +59,46 @@ module Imb
|
|
83
59
|
false
|
84
60
|
end
|
85
61
|
|
62
|
+
# @!group Internal
|
63
|
+
|
64
|
+
# Convert a string representation of a routing code into
|
65
|
+
# an array that can be passed to the constructor.
|
66
|
+
# +s+ is a string of length:
|
67
|
+
# * 0 - no routing code
|
68
|
+
# * 5 - zip
|
69
|
+
# * 9 - zip + plus4
|
70
|
+
# * 11 - zip + plus4 + delivery point
|
71
|
+
# The result is an array of [zip, zip4, delivery point]
|
72
|
+
|
73
|
+
def self.string_to_array(s)
|
74
|
+
s = s.gsub(/[\D]/, '')
|
75
|
+
match = /^(?:(\d{5})(?:(\d{4})(\d{2})?)?)?$/.match(s)
|
76
|
+
unless match
|
77
|
+
raise ArgumentError, "Bad routing code: #{s.inspect}"
|
78
|
+
end
|
79
|
+
zip, plus4, delivery_point = match.to_a[1..-1]
|
80
|
+
[zip, plus4, delivery_point]
|
81
|
+
end
|
82
|
+
|
83
|
+
# Validate the value.
|
84
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
85
|
+
# @raise ArgumentError if invalid
|
86
|
+
|
87
|
+
def validate(long_mailer_id)
|
88
|
+
end
|
89
|
+
|
86
90
|
# Add this object's value to target, shifting it left as many
|
87
91
|
# digts as are needed to make room.
|
92
|
+
# @param [Integer] target The target to be shifted and added to
|
93
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
94
|
+
# @return [Integer] The new value of the target
|
88
95
|
|
89
96
|
def shift_and_add_to(target, long_mailer_id)
|
90
97
|
target * 10 ** NUM_DIGITS + convert
|
91
98
|
end
|
92
99
|
|
100
|
+
# @!endgroup
|
101
|
+
|
93
102
|
protected
|
94
103
|
|
95
104
|
# Convert to an array of [zip, plus4, delivery point]
|
@@ -5,9 +5,10 @@ module Imb
|
|
5
5
|
class SerialNumber
|
6
6
|
|
7
7
|
# Turn the argument into a SerialNumber if possible. Accepts:
|
8
|
-
# * SerialNumber
|
8
|
+
# * {SerialNumber}
|
9
9
|
# * String
|
10
10
|
# * Integer
|
11
|
+
# @return [SerialNumber]
|
11
12
|
|
12
13
|
def self.coerce(o)
|
13
14
|
case o
|
@@ -22,14 +23,32 @@ module Imb
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
#
|
26
|
+
# @param [Integer] value
|
26
27
|
|
27
28
|
def initialize(value)
|
28
29
|
@value = value
|
29
30
|
end
|
30
31
|
|
31
|
-
#
|
32
|
-
#
|
32
|
+
# Return true if this object is equal to o
|
33
|
+
# @param [Object] o Any object acceptable to {.coerce}
|
34
|
+
|
35
|
+
def ==(o)
|
36
|
+
SerialNumber.coerce(o).to_i == to_i
|
37
|
+
rescue ArgumentError
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Integer] The value of the serial number
|
42
|
+
|
43
|
+
def to_i
|
44
|
+
@value
|
45
|
+
end
|
46
|
+
|
47
|
+
# @!group Internal
|
48
|
+
|
49
|
+
# Validate the value.
|
50
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
51
|
+
# @raise ArgumentError if invalid
|
33
52
|
|
34
53
|
def validate(long_mailer_id)
|
35
54
|
range = 0..max_value(long_mailer_id)
|
@@ -38,27 +57,17 @@ module Imb
|
|
38
57
|
end
|
39
58
|
end
|
40
59
|
|
41
|
-
# Return true if +o+ is equal. +o+ may be any object which ::coerce
|
42
|
-
# can turn into a SerialNumber.
|
43
|
-
|
44
|
-
def ==(o)
|
45
|
-
SerialNumber.coerce(o).to_i == to_i
|
46
|
-
rescue ArgumentError
|
47
|
-
false
|
48
|
-
end
|
49
|
-
|
50
60
|
# Add this object's value to target, shifting it left as many
|
51
61
|
# digts as are needed to make room.
|
62
|
+
# @param [Integer] target The target to be shifted and added to
|
63
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
64
|
+
# @return [Integer] The new value of the target
|
52
65
|
|
53
66
|
def shift_and_add_to(target, long_mailer_id)
|
54
67
|
target * 10 ** num_digits(long_mailer_id) + to_i
|
55
68
|
end
|
56
69
|
|
57
|
-
#
|
58
|
-
|
59
|
-
def to_i
|
60
|
-
@value
|
61
|
-
end
|
70
|
+
# @!endgroup
|
62
71
|
|
63
72
|
private
|
64
73
|
|
@@ -8,7 +8,7 @@ module Imb
|
|
8
8
|
RANGE = 0..999
|
9
9
|
|
10
10
|
# Turn the argument into a ServiceType if possible. Accepts:
|
11
|
-
# * ServiceType
|
11
|
+
# * {ServiceType}
|
12
12
|
# * String
|
13
13
|
# * Integer
|
14
14
|
|
@@ -25,23 +25,14 @@ module Imb
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
#
|
28
|
+
# @param [Integer] value
|
29
29
|
|
30
30
|
def initialize(value)
|
31
31
|
@value = value
|
32
32
|
end
|
33
33
|
|
34
|
-
#
|
35
|
-
#
|
36
|
-
|
37
|
-
def validate(long_mailer_id)
|
38
|
-
unless (RANGE) === @value
|
39
|
-
raise ArgumentError, "Must be #{RANGE}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# Return true if +o+ is equal. +o+ may be any object which ::coerce
|
44
|
-
# can turn into a ServiceType.
|
34
|
+
# Return true if this object is equal to o
|
35
|
+
# @param [Object] o Any object acceptable to {.coerce}
|
45
36
|
|
46
37
|
def ==(o)
|
47
38
|
ServiceType.coerce(o).to_i == to_i
|
@@ -49,18 +40,35 @@ module Imb
|
|
49
40
|
false
|
50
41
|
end
|
51
42
|
|
43
|
+
# @return [Integer] The value of the service type
|
44
|
+
|
45
|
+
def to_i
|
46
|
+
@value
|
47
|
+
end
|
48
|
+
|
49
|
+
# @!group Internal
|
50
|
+
|
51
|
+
# Validate the value.
|
52
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
53
|
+
# @raise ArgumentError if invalid
|
54
|
+
|
55
|
+
def validate(long_mailer_id)
|
56
|
+
unless (RANGE) === @value
|
57
|
+
raise ArgumentError, "Must be #{RANGE}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
52
61
|
# Add this object's value to target, shifting it left as many
|
53
62
|
# digts as are needed to make room.
|
63
|
+
# @param [Integer] target The target to be shifted and added to
|
64
|
+
# @param long_mailer_id truthy if the mailer ID is long (9 digits).
|
65
|
+
# @return [Integer] The new value of the target
|
54
66
|
|
55
67
|
def shift_and_add_to(target, long_mailer_id)
|
56
68
|
target * 10 ** NUM_DIGITS + to_i
|
57
69
|
end
|
58
70
|
|
59
|
-
#
|
60
|
-
|
61
|
-
def to_i
|
62
|
-
@value
|
63
|
-
end
|
71
|
+
# @!endgroup
|
64
72
|
|
65
73
|
private
|
66
74
|
|
metadata
CHANGED
@@ -1,81 +1,122 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: USPS-intelligent-barcode
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 3
|
10
|
+
version: 0.2.3
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Wayne Conrad
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2012-12-31 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: andand
|
16
|
-
|
22
|
+
prerelease: false
|
23
|
+
type: :runtime
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
25
|
none: false
|
18
|
-
requirements:
|
26
|
+
requirements:
|
19
27
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 9
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 3
|
33
|
+
version: "1.3"
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
26
36
|
name: memoizer
|
27
|
-
|
37
|
+
prerelease: false
|
38
|
+
type: :runtime
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
40
|
none: false
|
29
|
-
requirements:
|
41
|
+
requirements:
|
30
42
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
|
33
|
-
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 15
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 0
|
48
|
+
version: "1.0"
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: jeweler
|
34
52
|
prerelease: false
|
35
|
-
|
36
|
-
|
37
|
-
name: rspec
|
38
|
-
requirement: &75111680 !ruby/object:Gem::Requirement
|
53
|
+
type: :development
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
55
|
none: false
|
40
|
-
requirements:
|
56
|
+
requirements:
|
41
57
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 31
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 8
|
63
|
+
version: "1.8"
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: rspec
|
45
67
|
prerelease: false
|
46
|
-
|
47
|
-
|
48
|
-
name: jeweler
|
49
|
-
requirement: &75111120 !ruby/object:Gem::Requirement
|
68
|
+
type: :development
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
70
|
none: false
|
51
|
-
requirements:
|
71
|
+
requirements:
|
52
72
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 27
|
75
|
+
segments:
|
76
|
+
- 2
|
77
|
+
- 12
|
78
|
+
version: "2.12"
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
59
81
|
name: simplecov
|
60
|
-
|
82
|
+
prerelease: false
|
83
|
+
type: :development
|
84
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
85
|
none: false
|
62
|
-
requirements:
|
86
|
+
requirements:
|
63
87
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
|
66
|
-
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 5
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
- 7
|
93
|
+
version: "0.7"
|
94
|
+
version_requirements: *id005
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: yard
|
67
97
|
prerelease: false
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
98
|
+
type: :development
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
hash: 27
|
105
|
+
segments:
|
106
|
+
- 0
|
107
|
+
- 8
|
108
|
+
version: "0.8"
|
109
|
+
version_requirements: *id006
|
110
|
+
description: A pure Ruby library to generate a USPS Intelligent Mail barcode. It generates the string of characters to print with one of the USPS Intelligent Mail barcode fonts.
|
72
111
|
email: wayne@databill.com
|
73
112
|
executables: []
|
113
|
+
|
74
114
|
extensions: []
|
75
|
-
|
115
|
+
|
116
|
+
extra_rdoc_files:
|
76
117
|
- LICENSE.md
|
77
118
|
- README.rdoc
|
78
|
-
files:
|
119
|
+
files:
|
79
120
|
- Gemfile
|
80
121
|
- Gemfile.lock
|
81
122
|
- LICENSE.md
|
@@ -113,31 +154,37 @@ files:
|
|
113
154
|
- spec/ServiceType_spec.rb
|
114
155
|
- spec/spec_helper.rb
|
115
156
|
homepage: http://github.com/wconrad/USPS-intelligent-barcode
|
116
|
-
licenses:
|
157
|
+
licenses:
|
117
158
|
- MIT
|
118
159
|
post_install_message:
|
119
160
|
rdoc_options: []
|
120
|
-
|
161
|
+
|
162
|
+
require_paths:
|
121
163
|
- lib
|
122
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
165
|
none: false
|
124
|
-
requirements:
|
125
|
-
- -
|
126
|
-
- !ruby/object:Gem::Version
|
127
|
-
|
128
|
-
segments:
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
hash: 3
|
170
|
+
segments:
|
129
171
|
- 0
|
130
|
-
|
131
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
version: "0"
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
174
|
none: false
|
133
|
-
requirements:
|
134
|
-
- -
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
|
175
|
+
requirements:
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
hash: 3
|
179
|
+
segments:
|
180
|
+
- 0
|
181
|
+
version: "0"
|
137
182
|
requirements: []
|
183
|
+
|
138
184
|
rubyforge_project:
|
139
185
|
rubygems_version: 1.8.17
|
140
186
|
signing_key:
|
141
187
|
specification_version: 3
|
142
188
|
summary: Generates a USPS Intelligent Mail Barcode.
|
143
189
|
test_files: []
|
190
|
+
|