{ lib, internal }: let inherit (builtins) filter map split ; inherit (lib) concatStringsSep toInt; inherit (internal) octetsToInt intToOctets; in rec { /** Parse an IP address string to a 32-bit integer. Also accepts integers (returns as-is). # Type ``` parse :: (String | Int) -> Int ``` # Example ```nix parse "192.168.1.1" => 3232235777 ``` */ parse = ip: if builtins.isInt ip then ip else let parts = filter builtins.isString (split "\\." ip); octets = map toInt parts; in octetsToInt octets; /** Format a 32-bit integer as an IP address string. Also accepts strings (returns as-is after validation). # Type ``` format :: (Int | String) -> String ``` # Example ```nix format 3232235777 => "192.168.1.1" ``` */ format = ip: if builtins.isString ip then ip else concatStringsSep "." (map toString (intToOctets ip)); /** Convert IP to list of octets. # Type ``` toOctets :: (String | Int) -> [Int] ``` # Example ```nix toOctets "192.168.1.1" => [192 168 1 1] ``` */ toOctets = ip: intToOctets (parse ip); /** Convert list of octets to integer. # Type ``` fromOctets :: [Int] -> Int ``` # Example ```nix fromOctets [192 168 1 1] => 3232235777 ``` */ fromOctets = octetsToInt; /** Add offset to an IP address. Returns integer; use format for string. # Type ``` add :: (String | Int) -> Int -> Int ``` # Example ```nix add "192.168.1.1" 10 => 3232235787 ``` */ add = ip: offset: (parse ip) + offset; /** Add offset to an IP address, return as string. # Type ``` addStr :: (String | Int) -> Int -> String ``` # Example ```nix addStr "192.168.1.1" 10 => "192.168.1.11" ``` */ addStr = ip: offset: format (add ip offset); /** Subtract offset from an IP address. Returns integer; use format for string. # Type ``` subtract :: (String | Int) -> Int -> Int ``` # Example ```nix subtract "192.168.1.10" 5 => 3232235781 ``` */ subtract = ip: offset: (parse ip) - offset; /** Subtract offset from an IP address, return as string. # Type ``` subtractStr :: (String | Int) -> Int -> String ``` # Example ```nix subtractStr "192.168.1.10" 5 => "192.168.1.5" ``` */ subtractStr = ip: offset: format (subtract ip offset); /** Calculate difference between two IPs (ip1 - ip2). # Type ``` diff :: (String | Int) -> (String | Int) -> Int ``` # Example ```nix diff "192.168.1.10" "192.168.1.1" => 9 ``` */ diff = ip1: ip2: (parse ip1) - (parse ip2); /** Compare two IP addresses. Returns -1 if ip1 < ip2, 0 if equal, 1 if ip1 > ip2. # Type ``` compare :: (String | Int) -> (String | Int) -> Int ``` # Example ```nix compare "192.168.1.1" "192.168.1.10" => -1 ``` */ compare = ip1: ip2: let a = parse ip1; b = parse ip2; in if a < b then -1 else if a > b then 1 else 0; /** Less than comparison. # Type ``` lt :: (String | Int) -> (String | Int) -> Bool ``` # Example ```nix lt "192.168.1.1" "192.168.1.10" => true ``` */ lt = ip1: ip2: (parse ip1) < (parse ip2); /** Less than or equal comparison. # Type ``` lte :: (String | Int) -> (String | Int) -> Bool ``` # Example ```nix lte "192.168.1.1" "192.168.1.1" => true ``` */ lte = ip1: ip2: (parse ip1) <= (parse ip2); /** Greater than comparison. # Type ``` gt :: (String | Int) -> (String | Int) -> Bool ``` # Example ```nix gt "192.168.1.10" "192.168.1.1" => true ``` */ gt = ip1: ip2: (parse ip1) > (parse ip2); /** Greater than or equal comparison. # Type ``` gte :: (String | Int) -> (String | Int) -> Bool ``` # Example ```nix gte "192.168.1.1" "192.168.1.1" => true ``` */ gte = ip1: ip2: (parse ip1) >= (parse ip2); /** Equality comparison. # Type ``` eq :: (String | Int) -> (String | Int) -> Bool ``` # Example ```nix eq "192.168.1.1" 3232235777 => true ``` */ eq = ip1: ip2: (parse ip1) == (parse ip2); /** Get minimum of two IPs (returns integer). # Type ``` min :: (String | Int) -> (String | Int) -> Int ``` # Example ```nix min "192.168.1.10" "192.168.1.1" => 3232235777 ``` */ min = ip1: ip2: let a = parse ip1; b = parse ip2; in if a < b then a else b; /** Get minimum of two IPs (returns string). # Type ``` minStr :: (String | Int) -> (String | Int) -> String ``` # Example ```nix minStr "192.168.1.10" "192.168.1.1" => "192.168.1.1" ``` */ minStr = ip1: ip2: format (min ip1 ip2); /** Get maximum of two IPs (returns integer). # Type ``` max :: (String | Int) -> (String | Int) -> Int ``` # Example ```nix max "192.168.1.1" "192.168.1.10" => 3232235786 ``` */ max = ip1: ip2: let a = parse ip1; b = parse ip2; in if a > b then a else b; /** Get maximum of two IPs (returns string). # Type ``` maxStr :: (String | Int) -> (String | Int) -> String ``` # Example ```nix maxStr "192.168.1.1" "192.168.1.10" => "192.168.1.10" ``` */ maxStr = ip1: ip2: format (max ip1 ip2); }