Skip to content

Commit 7b8e3f6

Browse files
raornsmortex
authored andcommitted
Define #succ and #pred methods
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 <raorn@raorn.name>
1 parent 032e824 commit 7b8e3f6

4 files changed

Lines changed: 118 additions & 0 deletions

File tree

lib/ipaddress/ipv4.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,35 @@ def each
476476
end
477477
end
478478

479+
#
480+
# Returns the successor to the IP address
481+
#
482+
# Example:
483+
#
484+
# ip = IPAddress("192.168.45.23/16")
485+
#
486+
# ip.succ.to_string
487+
# => "192.168.45.24/16"
488+
#
489+
def succ
490+
self.class.new("#{IPAddress.ntoa(to_u32.succ % 0x100000000)}/#{prefix}")
491+
end
492+
alias_method :next, :succ
493+
494+
#
495+
# Returns the predecessor to the IP address
496+
#
497+
# Example:
498+
#
499+
# ip = IPAddress("192.168.45.23/16")
500+
#
501+
# ip.pred.to_string
502+
# => "192.168.45.22/16"
503+
#
504+
def pred
505+
self.class.new("#{IPAddress.ntoa(to_u32.pred % 0x100000000)}/#{prefix}")
506+
end
507+
479508
#
480509
# Spaceship operator to compare IPv4 objects
481510
#

lib/ipaddress/ipv6.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,35 @@ def each
461461
end
462462
end
463463

464+
#
465+
# Returns the successor to the IP address
466+
#
467+
# Example:
468+
#
469+
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
470+
#
471+
# ip6.succ.to_string
472+
# => "2001:db8::8:800:200c:417b/64"
473+
#
474+
def succ
475+
IPAddress::IPv6.parse_u128(to_u128.succ, prefix)
476+
end
477+
alias_method :next, :succ
478+
479+
#
480+
# Returns the predecessor to the IP address
481+
#
482+
# Example:
483+
#
484+
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
485+
#
486+
# ip6.pred.to_string
487+
# => "2001:db8::8:800:200c:4179/64"
488+
#
489+
def pred
490+
IPAddress::IPv6.parse_u128(to_u128.pred, prefix)
491+
end
492+
464493
#
465494
# Spaceship operator to compare IPv6 objects
466495
#

test/ipaddress/ipv4_test.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,36 @@ def test_method_each
241241
assert_equal expected, arr
242242
end
243243

244+
def test_method_succ
245+
ip = @klass.new("192.168.100.0/24")
246+
assert_instance_of @klass, ip.succ
247+
assert_equal "192.168.100.1/24", ip.succ.to_string
248+
ip = @klass.new("192.168.100.50/24")
249+
assert_instance_of @klass, ip.succ
250+
assert_equal "192.168.100.51/24", ip.succ.to_string
251+
ip = @klass.new("0.0.0.0/32")
252+
assert_instance_of @klass, ip.succ
253+
assert_equal "0.0.0.1/32", ip.succ.to_string
254+
ip = @klass.new("255.255.255.255/32")
255+
assert_instance_of @klass, ip.succ
256+
assert_equal "0.0.0.0/32", ip.succ.to_string
257+
end
258+
259+
def test_method_pred
260+
ip = @klass.new("192.168.100.0/24")
261+
assert_instance_of @klass, ip.pred
262+
assert_equal "192.168.99.255/24", ip.pred.to_string
263+
ip = @klass.new("192.168.100.50/24")
264+
assert_instance_of @klass, ip.pred
265+
assert_equal "192.168.100.49/24", ip.pred.to_string
266+
ip = @klass.new("0.0.0.0/32")
267+
assert_instance_of @klass, ip.pred
268+
assert_equal "255.255.255.255/32", ip.pred.to_string
269+
ip = @klass.new("255.255.255.255/32")
270+
assert_instance_of @klass, ip.pred
271+
assert_equal "255.255.255.254/32", ip.pred.to_string
272+
end
273+
244274
def test_method_size
245275
ip = @klass.new("10.0.0.1/29")
246276
assert_equal 8, ip.size

test/ipaddress/ipv6_test.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,36 @@ def test_method_each
234234
assert_equal expected, arr
235235
end
236236

237+
def test_method_succ
238+
ip = @klass.new("2001:db8:0:cd30::/64")
239+
assert_instance_of @klass, ip.succ
240+
assert_equal "2001:db8:0:cd30::1/64", ip.succ.to_string
241+
ip = @klass.new("::")
242+
assert_instance_of @klass, ip.succ
243+
assert_equal "::1/128", ip.succ.to_string
244+
ip = @klass.new("::1")
245+
assert_instance_of @klass, ip.succ
246+
assert_equal "::2/128", ip.succ.to_string
247+
ip = @klass.new("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64")
248+
assert_instance_of @klass, ip.succ
249+
assert_equal "::/64", ip.succ.to_string
250+
end
251+
252+
def test_method_pred
253+
ip = @klass.new("2001:db8:0:cd30::/64")
254+
assert_instance_of @klass, ip.pred
255+
assert_equal "2001:db8:0:cd2f:ffff:ffff:ffff:ffff/64", ip.pred.to_string
256+
ip = @klass.new("::")
257+
assert_instance_of @klass, ip.pred
258+
assert_equal "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", ip.pred.to_string
259+
ip = @klass.new("::1")
260+
assert_instance_of @klass, ip.pred
261+
assert_equal "::/128", ip.pred.to_string
262+
ip = @klass.new("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64")
263+
assert_instance_of @klass, ip.pred
264+
assert_equal "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/64", ip.pred.to_string
265+
end
266+
237267
def test_method_compare
238268
ip1 = @klass.new("2001:db8:1::1/64")
239269
ip2 = @klass.new("2001:db8:2::1/64")

0 commit comments

Comments
 (0)