tvl-depot/users/sterni/nix/url/default.nix

101 lines
1.6 KiB
Nix
Raw Normal View History

{ depot, lib, ... }:
let
inherit (depot.users.sterni.nix)
char
int
string
flow
;
reserved = c: builtins.elem c [
"!"
"#"
"$"
"&"
"'"
"("
")"
"*"
"+"
","
"/"
":"
";"
"="
"?"
"@"
"["
"]"
];
unreserved = c: char.asciiAlphaNum c
|| builtins.elem c [ "-" "_" "." "~" ];
percentEncode = c:
if unreserved c
then c
else "%" + (string.fit
{
width = 2;
char = "0";
side = "left";
}
(int.toHex (char.ord c)));
encode = { leaveReserved ? false }: s:
let
chars = lib.stringToCharacters s;
tr = c:
if leaveReserved && reserved c
then c
else percentEncode c;
in
lib.concatStrings (builtins.map tr chars);
decode = s:
let
tokens = builtins.split "%" s;
decodeStep =
{ result ? ""
, inPercent ? false
}: s:
flow.cond [
[
(builtins.isList s)
{
inherit result;
inPercent = true;
}
]
[
inPercent
{
inPercent = false;
# first two characters came after an %
# the rest is the string until the next %
result = result
+ char.chr (int.fromHex (string.take 2 s))
+ (string.drop 2 s);
}
]
[
(!inPercent)
{
result = result + s;
}
]
];
in
(builtins.foldl' decodeStep { } tokens).result;
in
{
inherit
encode
decode
;
}