Skip to content

Commit

Permalink
Add a JSON addition for Enumerator::ArithmeticSequence
Browse files Browse the repository at this point in the history
  • Loading branch information
havenwood committed May 7, 2024
1 parent 4f876a8 commit 04e299a
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@
# - Complex: <tt>require 'json/add/complex'</tt>
# - Date: <tt>require 'json/add/date'</tt>
# - DateTime: <tt>require 'json/add/date_time'</tt>
# - Enumerator::ArithmeticSequence: <tt>require 'json/add/arithmetic_sequence'</tt>
# - Exception: <tt>require 'json/add/exception'</tt>
# - OpenStruct: <tt>require 'json/add/ostruct'</tt>
# - Range: <tt>require 'json/add/range'</tt>
Expand Down
59 changes: 59 additions & 0 deletions lib/json/add/arithmetic_sequence.rb
Original file line number Diff line number Diff line change
@@ -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 <tt>Enumerator::ArithmeticSequence#as_json</tt> and
# +Enumerator::ArithmeticSequence.json_create+ can be used to serialize and
# deserialize an \ArithmeticSequence object. See Marshal[rdoc-ref:Marshal].
#
# \Method <tt>Enumerator::ArithmeticSequence#as_json</tt> 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
8 changes: 8 additions & 0 deletions tests/json_addition_test.rb
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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

0 comments on commit 04e299a

Please sign in to comment.