diff --git a/lib/json.rb b/lib/json.rb
index 807488ffe..ad605bb3d 100644
--- a/lib/json.rb
+++ b/lib/json.rb
@@ -408,6 +408,7 @@
# - Complex: require 'json/add/complex'
# - Date: require 'json/add/date'
# - DateTime: require 'json/add/date_time'
+# - Enumerator::ArithmeticSequence: require 'json/add/arithmetic_sequence'
# - Exception: require 'json/add/exception'
# - OpenStruct: require 'json/add/ostruct'
# - Range: require 'json/add/range'
diff --git a/lib/json/add/arithmetic_sequence.rb b/lib/json/add/arithmetic_sequence.rb
new file mode 100644
index 000000000..784006fa0
--- /dev/null
+++ b/lib/json/add/arithmetic_sequence.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'json' unless defined?(JSON::JSON_LOADED) && JSON::JSON_LOADED
+
+class Enumerator
+ class ArithmeticSequence
+ # See #as_json.
+ def self.json_create(object)
+ Range.new(*object.values_at('b', 'e', 'x')) % object['s']
+ end
+
+ # Methods Enumerator::ArithmeticSequence#as_json and
+ # +Enumerator::ArithmeticSequence.json_create+ can be used to serialize and
+ # deserialize an \ArithmeticSequence object. See Marshal[rdoc-ref:Marshal].
+ #
+ # \Method Enumerator::ArithmeticSequence#as_json serializes +self+,
+ # returning a 5-element hash representing +self+:
+ #
+ # require 'json/add/arithmetic_sequence'
+ #
+ # x = 42.step(by: 3, to: 72).as_json
+ # # => {"json_class"=>"Enumerator::ArithmeticSequence", "b"=>42, "e"=>72, "x"=>false, "s"=>3}
+ #
+ # y = ((42...72) % 4).as_json
+ # # => {"json_class"=>"Enumerator::ArithmeticSequence", "b"=>42, "e"=>72, "x"=>true, "s"=>4}
+ #
+ # \Method +JSON.create+ deserializes such a hash, returning an
+ # \ArithmeticSequence object:
+ #
+ # Enumerator::ArithmeticSequence.json_create(x) # => ((42..72).%(3))
+ # Enumerator::ArithmeticSequence.json_create(y) # => ((42...72).%(4))
+ #
+ def as_json(*)
+ {
+ JSON.create_id => self.class.name,
+ 'b' => self.begin,
+ 'e' => self.end,
+ 'x' => exclude_end?,
+ 's' => step
+ }
+ end
+
+ # Returns a JSON string representing +self+:
+ #
+ # require 'json/add/arithmetic_sequence'
+ #
+ # puts 42.step(by: 3, to: 72).to_json
+ # puts ((42...72) % 4).to_json
+ #
+ # Output:
+ #
+ # {"json_class":"Enumerator::ArithmeticSequence","b":42,"e":72,"x":false,"s":3}
+ # {"json_class":"Enumerator::ArithmeticSequence","b":42,"e":72,"x":true,"s":4}
+ #
+ def to_json(*args)
+ as_json.to_json(*args)
+ end
+ end
+end
diff --git a/tests/json_addition_test.rb b/tests/json_addition_test.rb
index 3a7a58176..70cb82528 100644
--- a/tests/json_addition_test.rb
+++ b/tests/json_addition_test.rb
@@ -1,5 +1,6 @@
#frozen_string_literal: false
require_relative 'test_helper'
+require 'json/add/arithmetic_sequence'
require 'json/add/core'
require 'json/add/complex'
require 'json/add/rational'
@@ -196,4 +197,11 @@ def test_set
s = Set.new([:a, :b, :c, :a])
assert_equal s, JSON.parse(JSON(s), :create_additions => true)
end
+
+ def test_arithmetic_sequence
+ include_end = 42.step(by: 3, to: 72)
+ assert_equal include_end, JSON.parse(JSON(include_end), :create_additions => true)
+ exclude_end = ((42...72) % 4)
+ assert_equal exclude_end, JSON.parse(JSON(exclude_end), :create_additions => true)
+ end
end