barcodevalidation 2.2.0 → 2.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 +4 -4
- data/barcodevalidation.gemspec +3 -0
- data/config/boot.rb +2 -0
- data/lib/barcodevalidation.rb +3 -0
- data/lib/barcodevalidation/digit.rb +4 -0
- data/lib/barcodevalidation/digit_sequence.rb +4 -0
- data/lib/barcodevalidation/error.rb +2 -0
- data/lib/barcodevalidation/error/argument_error_class.rb +2 -0
- data/lib/barcodevalidation/gtin.rb +18 -33
- data/lib/barcodevalidation/gtin/base.rb +102 -0
- data/lib/barcodevalidation/gtin/check_digit.rb +29 -0
- data/lib/barcodevalidation/gtin/gtin12.rb +9 -0
- data/lib/barcodevalidation/gtin/gtin13.rb +9 -0
- data/lib/barcodevalidation/gtin/gtin14.rb +9 -0
- data/lib/barcodevalidation/gtin/gtin8.rb +9 -0
- data/lib/barcodevalidation/invalid_gtin.rb +3 -0
- data/lib/barcodevalidation/mixin.rb +2 -0
- data/lib/barcodevalidation/mixin/has_check_digit.rb +2 -0
- data/lib/barcodevalidation/mixin/value_object.rb +2 -0
- data/lib/barcodevalidation/version.rb +3 -1
- metadata +15 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0ddfbb1e0066701228173d80f24f18eca5bf195e4cb0ba84d1a2b7cff1f306b
|
4
|
+
data.tar.gz: 21fd5a0a5eb2876b5b764c49d0ae2a4130a2cd4710e0ee3784b56221f5d0c895
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eac5d8884e82da6c0f57b1042887d8337a6f1bebb91062b068919f42513e90a869edfd048389fd4529a08537a326a582dcd9d0110e327d8dd1726cd93eebb0fb
|
7
|
+
data.tar.gz: 8448952e7fa2e83336f67de3af3b6b1f3cee49d57ed180df5402c4d9b85136fa332ee345b4c4a8c024be909d709125e29d7ca42c0df228e4a5013b0d4c6e4d4c
|
data/barcodevalidation.gemspec
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path("lib", __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
require "barcodevalidation/version"
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
8
|
+
spec.required_ruby_version = "~> 2.5"
|
6
9
|
spec.name = "barcodevalidation"
|
7
10
|
spec.version = BarcodeValidation::VERSION
|
8
11
|
spec.authors = ["Marketplacer"]
|
data/config/boot.rb
CHANGED
data/lib/barcodevalidation.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "barcodevalidation/mixin"
|
2
4
|
require "barcodevalidation/error"
|
3
5
|
require "barcodevalidation/digit"
|
@@ -23,6 +25,7 @@ module BarcodeValidation
|
|
23
25
|
# Strips punctuation
|
24
26
|
def sanitize(input)
|
25
27
|
return input.gsub(/(\s|[-_])/, "") if input.respond_to? :gsub
|
28
|
+
|
26
29
|
input
|
27
30
|
end
|
28
31
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "delegate"
|
4
|
+
require_relative "error/argument_error_class"
|
2
5
|
|
3
6
|
module BarcodeValidation
|
4
7
|
class Digit < DelegateClass(Integer)
|
@@ -10,6 +13,7 @@ module BarcodeValidation
|
|
10
13
|
def initialize(input)
|
11
14
|
value = Integer(input)
|
12
15
|
raise ::ArgumentError unless (0..9).cover? value
|
16
|
+
|
13
17
|
super(value)
|
14
18
|
rescue *INTEGER_CAST_ERRORS
|
15
19
|
raise Digit::ArgumentError, input
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "forwardable"
|
4
|
+
require_relative "error/argument_error_class"
|
2
5
|
|
3
6
|
module BarcodeValidation
|
4
7
|
class DigitSequence < Array
|
@@ -18,6 +21,7 @@ module BarcodeValidation
|
|
18
21
|
def initialize(values)
|
19
22
|
values = cast(values)
|
20
23
|
raise ArgumentError, values unless values.respond_to? :map
|
24
|
+
|
21
25
|
super(values.map { |value| BarcodeValidation::Digit.new(value) })
|
22
26
|
end
|
23
27
|
|
@@ -1,42 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "forwardable"
|
4
|
+
require_relative "invalid_gtin"
|
5
|
+
require_relative "gtin/base"
|
6
|
+
require_relative "gtin/check_digit"
|
7
|
+
require_relative "gtin/gtin8"
|
8
|
+
require_relative "gtin/gtin12"
|
9
|
+
require_relative "gtin/gtin13"
|
10
|
+
require_relative "gtin/gtin14"
|
2
11
|
|
3
12
|
module BarcodeValidation
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
VALID_LENGTHS = [8, 12, 13, 14].freeze
|
9
|
-
|
10
|
-
def self.new(input)
|
11
|
-
super
|
12
|
-
rescue BarcodeValidation::Error => e
|
13
|
-
InvalidGTIN.new(input, error: e)
|
14
|
-
end
|
15
|
-
|
16
|
-
def valid?
|
17
|
-
VALID_LENGTHS.include?(length) && check_digit.valid?
|
18
|
-
end
|
19
|
-
|
20
|
-
class CheckDigit < DelegateClass(Digit)
|
21
|
-
include Adamantium::Flat
|
22
|
-
include Mixin::ValueObject
|
23
|
-
|
24
|
-
attr_reader :actual, :expected
|
25
|
-
|
26
|
-
def initialize(actual, expected: nil)
|
27
|
-
expected = actual if expected.nil?
|
28
|
-
@expected = Digit.new(expected)
|
29
|
-
@actual = Digit.new(actual)
|
30
|
-
super(@actual)
|
13
|
+
module GTIN
|
14
|
+
class << self
|
15
|
+
def new(input)
|
16
|
+
(class_for_input(input) || BarcodeValidation::InvalidGTIN).new(input)
|
31
17
|
end
|
32
18
|
|
33
|
-
|
34
|
-
actual == expected
|
35
|
-
end
|
19
|
+
private
|
36
20
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
21
|
+
def class_for_input(input)
|
22
|
+
[GTIN8, GTIN12, GTIN13, GTIN14].find do |klass|
|
23
|
+
input.to_s.size == klass::VALID_LENGTH
|
24
|
+
end
|
40
25
|
end
|
41
26
|
end
|
42
27
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module BarcodeValidation
|
6
|
+
module GTIN
|
7
|
+
class Base < BarcodeValidation::DigitSequence
|
8
|
+
MODULUS = 10
|
9
|
+
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
attr_reader :input
|
13
|
+
|
14
|
+
def initialize(input)
|
15
|
+
@input = input
|
16
|
+
|
17
|
+
super
|
18
|
+
rescue BarcodeValidation::Error => e
|
19
|
+
BarcodeValidation::InvalidGTIN.new(input, error: e)
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid?
|
23
|
+
valid_length == length && check_digit.valid?
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_length
|
27
|
+
raise(AbstractMethodError, "Concrete classes must define the VALID_LENGTH constant") unless self.class.const_defined?(:VALID_LENGTH)
|
28
|
+
|
29
|
+
self.class::VALID_LENGTH
|
30
|
+
end
|
31
|
+
|
32
|
+
class AbstractMethodError < StandardError; end
|
33
|
+
|
34
|
+
def to_all_valid
|
35
|
+
[
|
36
|
+
to_gtin_8,
|
37
|
+
to_gtin_12,
|
38
|
+
to_gtin_13,
|
39
|
+
to_gtin_14,
|
40
|
+
].select(&:valid?)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_gtin_8
|
44
|
+
is_a?(GTIN8) ? self : transcode_to(GTIN8)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_gtin_12
|
48
|
+
is_a?(GTIN12) ? self : transcode_to(GTIN12)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_gtin_13
|
52
|
+
is_a?(GTIN13) ? self : transcode_to(GTIN13)
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_gtin_14
|
56
|
+
is_a?(GTIN14) ? self : transcode_to(GTIN14)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def check_digit
|
62
|
+
CheckDigit.new(last, expected: expected_check_digit)
|
63
|
+
end
|
64
|
+
|
65
|
+
def expected_check_digit
|
66
|
+
(MODULUS - weighted_checkable_digit_sum) % MODULUS
|
67
|
+
end
|
68
|
+
|
69
|
+
def weighted_checkable_digit_sum
|
70
|
+
checkable_digits
|
71
|
+
.zip([3, 1].cycle)
|
72
|
+
.map { |digit, factor| digit * factor }
|
73
|
+
.reduce(&:+)
|
74
|
+
end
|
75
|
+
|
76
|
+
def checkable_digits
|
77
|
+
take(length - 1).reverse.map(&:to_i)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Instantiates the given class with the string value of this instance
|
81
|
+
# with any leading zeros stripped out, and then zero-padded up to the
|
82
|
+
# valid length of the given class. If the resulting string is <> the
|
83
|
+
# valid length of the target format, the returned object will be a
|
84
|
+
# BarcodeValidation::InvalidGTIN with valid? = false and a meaningful
|
85
|
+
# error message.
|
86
|
+
def transcode_to(klass)
|
87
|
+
gtin = klass.new(format("%0#{klass::VALID_LENGTH}d", to_s.gsub(/^0+/, "")))
|
88
|
+
|
89
|
+
if gtin.valid?
|
90
|
+
gtin
|
91
|
+
else
|
92
|
+
BarcodeValidation::InvalidGTIN.new(
|
93
|
+
input,
|
94
|
+
error: klass::ConversionError.new(klass).exception(input),
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
ConversionError = Error::ArgumentErrorClass.new(self)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BarcodeValidation
|
4
|
+
module GTIN
|
5
|
+
class CheckDigit < DelegateClass(Digit)
|
6
|
+
include Adamantium::Flat
|
7
|
+
include Mixin::ValueObject
|
8
|
+
|
9
|
+
attr_reader :actual, :expected
|
10
|
+
|
11
|
+
def initialize(actual, expected: nil)
|
12
|
+
expected = actual if expected.nil?
|
13
|
+
@expected = Digit.new(expected)
|
14
|
+
@actual = Digit.new(actual)
|
15
|
+
super(@actual)
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid?
|
19
|
+
actual == expected
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
return super if valid?
|
24
|
+
|
25
|
+
"#<#{self.class}(#{actual}) invalid: expected #{expected}>"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: barcodevalidation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marketplacer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: adamantium
|
@@ -41,6 +41,12 @@ files:
|
|
41
41
|
- lib/barcodevalidation/error.rb
|
42
42
|
- lib/barcodevalidation/error/argument_error_class.rb
|
43
43
|
- lib/barcodevalidation/gtin.rb
|
44
|
+
- lib/barcodevalidation/gtin/base.rb
|
45
|
+
- lib/barcodevalidation/gtin/check_digit.rb
|
46
|
+
- lib/barcodevalidation/gtin/gtin12.rb
|
47
|
+
- lib/barcodevalidation/gtin/gtin13.rb
|
48
|
+
- lib/barcodevalidation/gtin/gtin14.rb
|
49
|
+
- lib/barcodevalidation/gtin/gtin8.rb
|
44
50
|
- lib/barcodevalidation/invalid_gtin.rb
|
45
51
|
- lib/barcodevalidation/mixin.rb
|
46
52
|
- lib/barcodevalidation/mixin/has_check_digit.rb
|
@@ -50,24 +56,24 @@ homepage: https://github.com/marketplacer/barcodevalidation
|
|
50
56
|
licenses:
|
51
57
|
- MIT
|
52
58
|
metadata: {}
|
53
|
-
post_install_message:
|
59
|
+
post_install_message:
|
54
60
|
rdoc_options: []
|
55
61
|
require_paths:
|
56
62
|
- lib
|
57
63
|
required_ruby_version: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
|
-
- - "
|
65
|
+
- - "~>"
|
60
66
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
67
|
+
version: '2.5'
|
62
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
69
|
requirements:
|
64
70
|
- - ">="
|
65
71
|
- !ruby/object:Gem::Version
|
66
72
|
version: '0'
|
67
73
|
requirements: []
|
68
|
-
rubyforge_project:
|
69
|
-
rubygems_version: 2.7.6
|
70
|
-
signing_key:
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.7.6.2
|
76
|
+
signing_key:
|
71
77
|
specification_version: 4
|
72
78
|
summary: Parses and validates barcodes
|
73
79
|
test_files: []
|