Skip to content

Commit

Permalink
Define #succ and #pred methods
Browse files Browse the repository at this point in the history
Example:

  ip = IPAddress("192.168.45.23/16")

  ip.pred.to_string
    => "192.168.45.22/16"

  ip6 = IPAddress("2001:db8::8:800:200c:417a/64")

  ip6.succ.to_string
    => "2001:db8::8:800:200c:417b/64"

This allows to use IPAddress objects in Range:

  range = IPAddress("192.168.1.15")..IPAddress("192.168.45.80")

  range.include IPAddress("192.168.22.47")
    => true

  range.include IPAddress("192.168.0.3")
    => false

Signed-off-by: Alexey I. Froloff <[email protected]>
  • Loading branch information
raorn authored and smortex committed Aug 30, 2017
1 parent 032e824 commit 7b8e3f6
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 0 deletions.
29 changes: 29 additions & 0 deletions lib/ipaddress/ipv4.rb
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,35 @@ def each
end
end

#
# Returns the successor to the IP address
#
# Example:
#
# ip = IPAddress("192.168.45.23/16")
#
# ip.succ.to_string
# => "192.168.45.24/16"
#
def succ
self.class.new("#{IPAddress.ntoa(to_u32.succ % 0x100000000)}/#{prefix}")
end
alias_method :next, :succ

#
# Returns the predecessor to the IP address
#
# Example:
#
# ip = IPAddress("192.168.45.23/16")
#
# ip.pred.to_string
# => "192.168.45.22/16"
#
def pred
self.class.new("#{IPAddress.ntoa(to_u32.pred % 0x100000000)}/#{prefix}")
end

#
# Spaceship operator to compare IPv4 objects
#
Expand Down
29 changes: 29 additions & 0 deletions lib/ipaddress/ipv6.rb
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,35 @@ def each
end
end

#
# Returns the successor to the IP address
#
# Example:
#
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
#
# ip6.succ.to_string
# => "2001:db8::8:800:200c:417b/64"
#
def succ
IPAddress::IPv6.parse_u128(to_u128.succ, prefix)
end
alias_method :next, :succ

#
# Returns the predecessor to the IP address
#
# Example:
#
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
#
# ip6.pred.to_string
# => "2001:db8::8:800:200c:4179/64"
#
def pred
IPAddress::IPv6.parse_u128(to_u128.pred, prefix)
end

#
# Spaceship operator to compare IPv6 objects
#
Expand Down
30 changes: 30 additions & 0 deletions test/ipaddress/ipv4_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,36 @@ def test_method_each
assert_equal expected, arr
end

def test_method_succ
ip = @klass.new("192.168.100.0/24")
assert_instance_of @klass, ip.succ
assert_equal "192.168.100.1/24", ip.succ.to_string
ip = @klass.new("192.168.100.50/24")
assert_instance_of @klass, ip.succ
assert_equal "192.168.100.51/24", ip.succ.to_string
ip = @klass.new("0.0.0.0/32")
assert_instance_of @klass, ip.succ
assert_equal "0.0.0.1/32", ip.succ.to_string
ip = @klass.new("255.255.255.255/32")
assert_instance_of @klass, ip.succ
assert_equal "0.0.0.0/32", ip.succ.to_string
end

def test_method_pred
ip = @klass.new("192.168.100.0/24")
assert_instance_of @klass, ip.pred
assert_equal "192.168.99.255/24", ip.pred.to_string
ip = @klass.new("192.168.100.50/24")
assert_instance_of @klass, ip.pred
assert_equal "192.168.100.49/24", ip.pred.to_string
ip = @klass.new("0.0.0.0/32")
assert_instance_of @klass, ip.pred
assert_equal "255.255.255.255/32", ip.pred.to_string
ip = @klass.new("255.255.255.255/32")
assert_instance_of @klass, ip.pred
assert_equal "255.255.255.254/32", ip.pred.to_string
end

def test_method_size
ip = @klass.new("10.0.0.1/29")
assert_equal 8, ip.size
Expand Down
30 changes: 30 additions & 0 deletions test/ipaddress/ipv6_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,36 @@ def test_method_each
assert_equal expected, arr
end

def test_method_succ
ip = @klass.new("2001:db8:0:cd30::/64")
assert_instance_of @klass, ip.succ
assert_equal "2001:db8:0:cd30::1/64", ip.succ.to_string
ip = @klass.new("::")
assert_instance_of @klass, ip.succ
assert_equal "::1/128", ip.succ.to_string
ip = @klass.new("::1")
assert_instance_of @klass, ip.succ
assert_equal "::2/128", ip.succ.to_string
ip = @klass.new("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64")
assert_instance_of @klass, ip.succ
assert_equal "::/64", ip.succ.to_string
end

def test_method_pred
ip = @klass.new("2001:db8:0:cd30::/64")
assert_instance_of @klass, ip.pred
assert_equal "2001:db8:0:cd2f:ffff:ffff:ffff:ffff/64", ip.pred.to_string
ip = @klass.new("::")
assert_instance_of @klass, ip.pred
assert_equal "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", ip.pred.to_string
ip = @klass.new("::1")
assert_instance_of @klass, ip.pred
assert_equal "::/128", ip.pred.to_string
ip = @klass.new("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64")
assert_instance_of @klass, ip.pred
assert_equal "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/64", ip.pred.to_string
end

def test_method_compare
ip1 = @klass.new("2001:db8:1::1/64")
ip2 = @klass.new("2001:db8:2::1/64")
Expand Down

0 comments on commit 7b8e3f6

Please sign in to comment.