diff options
author | tv <tv@krebsco.de> | 2017-04-13 11:12:55 +0200 |
---|---|---|
committer | tv <tv@krebsco.de> | 2017-04-13 11:12:55 +0200 |
commit | f93e1d466f9454dc5e10ac9903cefa281407db29 (patch) | |
tree | ce369930bd165a033d1152095479250a365fc580 /lib | |
parent | 7baf4a4090583eaac4e369fffc91764e1990841e (diff) |
lib: add normalize-ip6-addr
Diffstat (limited to 'lib')
-rw-r--r-- | lib/default.nix | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/default.nix b/lib/default.nix index 7e61c9413..9399a0107 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 |