Skip to content

Commit 8544c16

Browse files
committed
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 2a10d48 commit 8544c16

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
@@ -454,6 +454,35 @@ def each
454454
end
455455
end
456456

457+
#
458+
# Returns the successor to the IP address
459+
#
460+
# Example:
461+
#
462+
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
463+
#
464+
# ip6.succ.to_string
465+
# => "2001:db8::8:800:200c:417b/64"
466+
#
467+
def succ
468+
IPAddress::IPv6.parse_u128(to_u128.succ, prefix)
469+
end
470+
alias_method :next, :succ
471+
472+
#
473+
# Returns the predecessor to the IP address
474+
#
475+
# Example:
476+
#
477+
# ip6 = IPAddress("2001:db8::8:800:200c:417a/64")
478+
#
479+
# ip6.pred.to_string
480+
# => "2001:db8::8:800:200c:4179/64"
481+
#
482+
def pred
483+
IPAddress::IPv6.parse_u128(to_u128.pred, prefix)
484+
end
485+
457486
#
458487
# Spaceship operator to compare IPv6 objects
459488
#

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
@@ -228,6 +228,36 @@ def test_method_each
228228
assert_equal expected, arr
229229
end
230230

231+
def test_method_succ
232+
ip = @klass.new("2001:db8:0:cd30::/64")
233+
assert_instance_of @klass, ip.succ
234+
assert_equal "2001:db8:0:cd30::1/64", ip.succ.to_string
235+
ip = @klass.new("::")
236+
assert_instance_of @klass, ip.succ
237+
assert_equal "::1/128", ip.succ.to_string
238+
ip = @klass.new("::1")
239+
assert_instance_of @klass, ip.succ
240+
assert_equal "::2/128", ip.succ.to_string
241+
ip = @klass.new("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64")
242+
assert_instance_of @klass, ip.succ
243+
assert_equal "::/64", ip.succ.to_string
244+
end
245+
246+
def test_method_pred
247+
ip = @klass.new("2001:db8:0:cd30::/64")
248+
assert_instance_of @klass, ip.pred
249+
assert_equal "2001:db8:0:cd2f:ffff:ffff:ffff:ffff/64", ip.pred.to_string
250+
ip = @klass.new("::")
251+
assert_instance_of @klass, ip.pred
252+
assert_equal "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", ip.pred.to_string
253+
ip = @klass.new("::1")
254+
assert_instance_of @klass, ip.pred
255+
assert_equal "::/128", ip.pred.to_string
256+
ip = @klass.new("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64")
257+
assert_instance_of @klass, ip.pred
258+
assert_equal "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/64", ip.pred.to_string
259+
end
260+
231261
def test_method_compare
232262
ip1 = @klass.new("2001:db8:1::1/64")
233263
ip2 = @klass.new("2001:db8:2::1/64")

0 commit comments

Comments
 (0)