lib/better_ipaddr/classes.rb in better_ipaddr-0.2.0 vs lib/better_ipaddr/classes.rb in better_ipaddr-0.2.1

- old
+ new

@@ -9,22 +9,135 @@ def inherited(cls) cls.extend BetterIpaddr::ClassMethods end + # Create an IPAddr from the given object. + # + # Returns nil if the object is of a type that can't be converted to an + # IPAddr. + # + # @param address [Integer, IPAddr, String] + # @param mask [Integer, IPAddr, String, Nil] + # @param family [Integer] + # @return [IPAddr, Nil] def self.[](address, mask = nil, family: self::FAMILY) - case mask + prefix_length = mask && object_to_prefix_length(mask, family) + + case address when Integer - if 0 <= mask && mask <= FAMILY_TO_BIT_LENGTH[family] - new(address, family).mask(mask) - else - new(address, family).mask(new(mask, family).to_s) - end - when String, IPAddr - new(address, family).mask(mask.to_s) + from_integer(address, prefix_length, family: family) + when IPAddr + from_ipaddr(address, prefix_length, family: family) + when String + from_string(address, prefix_length, family: family) + end + end + + # Create an IPAddr from an Integer. + # + # @param address [Integer] + # @param mask [Integer, String] a netmask or prefix length + # @param family [Integer, Nil] + # @return [IPAddr] + def self.from_integer(address, prefix_length, family: self::FAMILY) + new(address, family).mask(prefix_length || FAMILY_TO_BIT_LENGTH[family]) + end + + # Create an IPAddr from an IPAddr. + # + # @param address [IPAddr] + # @param mask [Integer, String] a netmask or prefix length + # @param family [Integer, Nil] + # @return [IPAddr] + def self.from_ipaddr(address, prefix_length, family: self::FAMILY) + new(address.to_i, family).mask(prefix_length || address.prefix_length) + end + + # Create an IPAddr from a String. + # + # @param address [String] + # @param mask [Integer, String] a netmask or prefix length + # @param family [Integer, Nil] + # @return [IPAddr] + def self.from_string(address, mask = nil, family: self::FAMILY) + if mask + new(address, family).mask(mask) else new(address, family) end + end + + # Convert an object to a prefix length. + # + # @param mask [Integer, String] + # @param family [Integer, Nil] + # @return [Integer] + def self.object_to_prefix_length(mask, family = self::FAMILY) + case mask + when Integer + integer_to_prefix_length(mask, family) + when String + string_to_prefix_length(mask, family) + when IPAddr + ipaddr_to_prefix_length(mask, family) + else + raise ArgumentError, "Can't convert #{mask.class} to prefix length" + end + end + + # Convert an integer to a prefix length. + # + # If the integer is within the range of possible prefix lengths, returns the + # same integer. Otherwise it assumes that the given integer is the integer + # representation of a netmask. + # + # Returns nil if the integer can't be converted. + # + # @param mask [Integer] + # @return [Integer] + def self.integer_to_prefix_length(mask, family = self::FAMILY) + if valid_prefix_length?(mask) + mask + else + NETMASK_TO_PREFIX_LENGTH[family][mask] || + (raise ArgumentError, "Can't convert #{mask} to prefix length") + end + end + + # Convert a netmask represented as an IPAddr to a prefix length. + # + # Returns nil if the IPAddr can't be converted. + # + # @param mask [IPAddr] + # @return [Integer] + def self.ipaddr_to_prefix_length(mask, family = self::FAMILY) + NETMASK_TO_PREFIX_LENGTH[family][mask.to_i] + end + + # Convert a string to a prefix length. + # + # Accepts the decimal representations of integers as well as netmasks in + # dotted quad notation. + # + # Returns nil if the string can't be converted. + # + # @param mask [String] + # @return [Integer] + def self.string_to_prefix_length(mask, family = self::FAMILY) + if mask =~ /^\d+$/ + integer_to_prefix_length(mask.to_i, family) + else + NETMASK_TO_PREFIX_LENGTH[family][new(mask).to_i] + end + end + + # Return true if the given number is a valid prefix length, false otherwise. + # + # @param prefix_length [Integer] + # @return [Boolean] + def self.valid_prefix_length?(prefix_length, family: self::FAMILY) + 0 <= prefix_length && prefix_length <= FAMILY_TO_BIT_LENGTH[family] end # Convert the given string to an IPAddr subclass. # # @param address [String] the string to convert