-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add: implement
utils.networking.portsToRanges
Signed-off-by: Janik H. <[email protected]>
- Loading branch information
1 parent
51e02ca
commit 266fe92
Showing
1 changed file
with
79 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,80 @@ | ||
{ lib, ... }: { | ||
/* | ||
Generates inclusive portrange given a lower and a higher number | ||
Type: | ||
utils.networking.portrange:: Int -> Int -> [ Int ] | ||
*/ | ||
portrange = | ||
from: | ||
to: | ||
let | ||
helper = input: | ||
if input.counter >= 0 then | ||
helper | ||
{ | ||
list = [ (from + input.counter) ] ++ input.list; | ||
counter = input.counter - 1; | ||
} else input.list; | ||
in | ||
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." | ||
helper | ||
{ list = [ ]; counter = to - from; } | ||
; | ||
{ lib, utils, ... }: let | ||
inherit (builtins) length head; | ||
inherit (lib.trivial) throwIf; | ||
inherit (lib.strings) concatStrings; | ||
inherit (lib.lists) foldr last range; | ||
inherit (utils.networking) splitWhen; | ||
in { | ||
|
||
/** | ||
# Description | ||
Generates inclusive portrange given a lower and a higher number, | ||
additionally throws an error if the end of the range is not strictly | ||
greater. | ||
# Type | ||
``` | ||
utils.networking.portrange :: Int -> Int -> [ Int ] | ||
``` | ||
*/ | ||
portrange = from: to: let ports = range from to; | ||
in throwIf (length ports == 0) (concatStrings [ | ||
"the second input has to be larger then the first one, " | ||
"otherwise you have a negative range which is impossible " | ||
"or not a range." | ||
]) ports; | ||
|
||
/** | ||
# Example | ||
```nix | ||
let formatRange = { start, end }: "${toString start}-${toString end}" | ||
in map (x: if isAttrs x then formatRange x else x) | ||
(portsToRanges [ 1 2 3 ]) | ||
=> [ "1-3" ] | ||
``` | ||
# Type | ||
``` | ||
utils.networking.portsToRanges :: [Int] -> [Int + { start end :: Int }] | ||
``` | ||
*/ | ||
portsToRanges = ports: let | ||
partitioned = splitWhen (a: b: a + 1 == b) ports; | ||
format = range: | ||
if length range == 1 | ||
then head range | ||
else { start = head range; end = last range; }; | ||
in map format partitioned; | ||
|
||
/** | ||
# Example | ||
```nix | ||
# split into strictly ordered sublists | ||
splitWhen (a: b: a < b) [ 7 8 9 4 5 6 1 2 3 ] | ||
=> [ [ 7 8 9 ] [ 4 5 6 ] [ 1 2 3 ] ] | ||
``` | ||
# Type | ||
``` | ||
utils.networking.splitWhen :: (a -> a -> Bool) -> [a] -> [[a]] | ||
``` | ||
*/ | ||
splitWhen = p: xs: let | ||
unfold = { xs, xss }: | ||
if length xs == 0 then xss else [xs] ++ xss; | ||
|
||
addElement = x: { xs, xss }: | ||
if length xs == 0 | ||
then { xs = [x]; inherit xss; } | ||
else if p x (head xs) | ||
then { xs = [x] ++ xs; inherit xss; } | ||
else { xs = [x]; xss = [xs] ++ xss; }; | ||
in unfold (foldr addElement { xs = []; xss = []; } xs); | ||
|
||
} |