Skip to content

Commit 8d62fda

Browse files
cpliJanik-Haag
authored andcommitted
add: implement utils.networking.portsToRanges
Signed-off-by: Janik H. <janik@aq0.de>
1 parent 51e02ca commit 8d62fda

File tree

1 file changed

+86
-21
lines changed

1 file changed

+86
-21
lines changed

utils/networking.nix

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,89 @@
1-
{ lib, ... }: {
2-
/*
3-
Generates inclusive portrange given a lower and a higher number
4-
5-
Type:
6-
utils.networking.portrange:: Int -> Int -> [ Int ]
7-
*/
8-
portrange =
9-
from:
10-
to:
1+
{ lib, utils, ... }:
2+
let
3+
inherit (builtins) length head;
4+
inherit (lib.trivial) throwIf;
5+
inherit (lib.strings) concatStrings;
6+
inherit (lib.lists) foldr last range;
7+
inherit (utils.networking) splitWhen;
8+
in
9+
{
10+
11+
/**
12+
# Description
13+
14+
Generates inclusive portrange given a lower and a higher number,
15+
additionally throws an error if the end of the range is not strictly
16+
greater.
17+
18+
# Type
19+
20+
```
21+
utils.networking.portrange :: Int -> Int -> [ Int ]
22+
```
23+
*/
24+
portrange = from: to:
25+
let ports = range from to;
26+
in throwIf (length ports == 0)
27+
(concatStrings [
28+
"the second input has to be larger then the first one, "
29+
"otherwise you have a negative range which is impossible "
30+
"or not a range."
31+
])
32+
ports;
33+
34+
/**
35+
# Example
36+
37+
```nix
38+
let formatRange = { start, end }: "${toString start}-${toString end}"
39+
in map (x: if isAttrs x then formatRange x else x)
40+
(portsToRanges [ 1 2 3 ])
41+
=> [ "1-3" ]
42+
```
43+
44+
# Type
45+
46+
```
47+
utils.networking.portsToRanges :: [Int] -> [Int + { start end :: Int }]
48+
```
49+
*/
50+
portsToRanges = ports:
1151
let
12-
helper = input:
13-
if input.counter >= 0 then
14-
helper
15-
{
16-
list = [ (from + input.counter) ] ++ input.list;
17-
counter = input.counter - 1;
18-
} else input.list;
52+
partitioned = splitWhen (a: b: a + 1 == b) ports;
53+
format = range:
54+
if length range == 1
55+
then head range
56+
else { start = head range; end = last range; };
1957
in
20-
lib.throwIf (from > to) "the second input has to be larger then the first one, otherwise you have a negative range which is impossible or not a range."
21-
helper
22-
{ list = [ ]; counter = to - from; }
23-
;
58+
map format partitioned;
59+
60+
/**
61+
# Example
62+
63+
```nix
64+
# split into strictly ordered sublists
65+
splitWhen (a: b: a < b) [ 7 8 9 4 5 6 1 2 3 ]
66+
=> [ [ 7 8 9 ] [ 4 5 6 ] [ 1 2 3 ] ]
67+
```
68+
69+
# Type
70+
71+
```
72+
utils.networking.splitWhen :: (a -> a -> Bool) -> [a] -> [[a]]
73+
```
74+
*/
75+
splitWhen = p: xs:
76+
let
77+
unfold = { xs, xss }:
78+
if length xs == 0 then xss else [ xs ] ++ xss;
79+
80+
addElement = x: { xs, xss }:
81+
if length xs == 0
82+
then { xs = [ x ]; inherit xss; }
83+
else if p x (head xs)
84+
then { xs = [ x ] ++ xs; inherit xss; }
85+
else { xs = [ x ]; xss = [ xs ] ++ xss; };
86+
in
87+
unfold (foldr addElement { xs = [ ]; xss = [ ]; } xs);
88+
2489
}

0 commit comments

Comments
 (0)