Files
nix-ip-utils/lib/ip.nix
2026-02-20 20:07:52 +00:00

393 lines
5.7 KiB
Nix

{ 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);
}