diff --git a/lib/ipaddress/ipv4.rb b/lib/ipaddress/ipv4.rb index a123e71..20c0c97 100644 --- a/lib/ipaddress/ipv4.rb +++ b/lib/ipaddress/ipv4.rb @@ -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 # diff --git a/lib/ipaddress/ipv6.rb b/lib/ipaddress/ipv6.rb index 6ae651d..34a9598 100644 --- a/lib/ipaddress/ipv6.rb +++ b/lib/ipaddress/ipv6.rb @@ -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 # diff --git a/test/ipaddress/ipv4_test.rb b/test/ipaddress/ipv4_test.rb index 19264e2..eb8d576 100644 --- a/test/ipaddress/ipv4_test.rb +++ b/test/ipaddress/ipv4_test.rb @@ -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 diff --git a/test/ipaddress/ipv6_test.rb b/test/ipaddress/ipv6_test.rb index 7eaa765..5047033 100644 --- a/test/ipaddress/ipv6_test.rb +++ b/test/ipaddress/ipv6_test.rb @@ -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")