summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2017-04-13 11:12:55 +0200
committertv <tv@krebsco.de>2017-04-13 11:12:55 +0200
commitf93e1d466f9454dc5e10ac9903cefa281407db29 (patch)
treece369930bd165a033d1152095479250a365fc580 /lib
parent7baf4a4090583eaac4e369fffc91764e1990841e (diff)
lib: add normalize-ip6-addr
Diffstat (limited to 'lib')
-rw-r--r--lib/default.nix46
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/default.nix b/lib/default.nix
index 7e61c941..9399a010 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -41,6 +41,52 @@ let
indent = replaceChars ["\n"] ["\n "];
+ # https://tools.ietf.org/html/rfc5952
+ normalize-ip6-addr =
+ let
+ max-run-0 =
+ let
+ both = v: { off = v; pos = v; };
+ gt = a: b: a.pos - a.off > b.pos - b.off;
+
+ chkmax = ctx: {
+ cur = both (ctx.cur.pos + 1);
+ max = if gt ctx.cur ctx.max then ctx.cur else ctx.max;
+ };
+
+ incpos = ctx: recursiveUpdate ctx {
+ cur.pos = ctx.cur.pos + 1;
+ };
+
+ f = ctx: blk: (if blk == "0" then incpos else chkmax) ctx;
+ z = { cur = both 0; max = both 0; };
+ in
+ blks: (chkmax (foldl' f z blks)).max;
+
+ group-zeros = a:
+ let
+ blks = splitString ":" a;
+ max = max-run-0 blks;
+ lhs = take max.off blks;
+ rhs = drop max.pos blks;
+ in
+ if max.pos == 0
+ then a
+ else "${concatStringsSep ":" lhs}::${concatStringsSep ":" rhs}";
+
+ drop-leading-zeros =
+ let
+ f = block:
+ let
+ res = match "0*(.+)" block;
+ in
+ if res == null
+ then block # empty block
+ else elemAt res 0;
+ in
+ a: concatStringsSep ":" (map f (splitString ":" a));
+ in
+ a: toLower (group-zeros (drop-leading-zeros a));
};
in