about summary refs log tree commit diff
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-04-23T17·05+0200
committerProfpatsch <mail@profpatsch.de>2021-04-24T09·54+0000
commit7e888c3c7bb36f6ab6e83d4a6f6a755ff4156791 (patch)
tree8ba54c21c976545c6d7cb6694aa24a6c425dde56
parentc98dd8b352c4dac33ebb7302eaf527eb4b681502 (diff)
feat(nix): add basic netstring nix generation functions r/2546
Moving to toplevel so I can use them with `runExecline`. They should
be pretty atomic, and are proven to work (tests are still in my user
dir, since they test the producers indirectly via the python parser
and I don’t want to pull it out right now).

Change-Id: Id0baa3adcb2ec646458a104c7868c2889b8c64f5
Reviewed-on: https://cl.tvl.fyi/c/depot/+/3054
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
-rw-r--r--nix/netstring/attrsToKeyValList.nix33
-rw-r--r--nix/netstring/fromString.nix10
-rw-r--r--users/Profpatsch/netstring/default.nix11
-rw-r--r--users/Profpatsch/netstring/tests/default.nix12
4 files changed, 48 insertions, 18 deletions
diff --git a/nix/netstring/attrsToKeyValList.nix b/nix/netstring/attrsToKeyValList.nix
new file mode 100644
index 000000000000..2805d0fbcef6
--- /dev/null
+++ b/nix/netstring/attrsToKeyValList.nix
@@ -0,0 +1,33 @@
+{ depot, lib, ... }:
+
+# Convert an attrset of strings to a list of key/value netstring pairs.
+# A good minimally viable json replacement if all you need is to iterate.
+# You can use e.g. `forstdin -Ed '' item` in execline to split the items
+# and then get the key and value via `multidefine -d '' $item { key value }`
+#
+# Example:
+#   { foo = "bar"; x = "abc"; }
+#   => "12:3:foo,3:bar,,10:1:x,3:abc,,"
+#
+# Example with runExecline:
+#   nix.runExecline "test" {
+#     stdin = nix.netstring.attrsToKeyValList {
+#       foo = "bar";
+#       x = "abc";
+#     };
+#   } [
+#     "forstdin" "-Ed" "" "item"
+#     "multidefine" "-d" "" "$item" [ "key" "value" ]
+#     "${pkgs.coreutils}/bin/echo" "\${key} -> \${value}"
+#   ]
+
+#   will print:
+#     foo -> bar
+#     x -> abc
+attrs:
+lib.concatStrings
+  (lib.mapAttrsToList
+    (k: v: depot.nix.netstring.fromString
+       ( depot.nix.netstring.fromString k
+       + depot.nix.netstring.fromString v))
+    attrs)
diff --git a/nix/netstring/fromString.nix b/nix/netstring/fromString.nix
new file mode 100644
index 000000000000..dcd688a8b0b3
--- /dev/null
+++ b/nix/netstring/fromString.nix
@@ -0,0 +1,10 @@
+{ ... }:
+# convert any nix string into a netstring
+# (prefixed by its length) according to https://en.wikipedia.org/wiki/Netstring
+#
+# Examples:
+#   netstring.fromString "foo"
+#   => "3:foo,"
+#   netstring.fromString ""
+#   => "0:,"
+s: "${toString (builtins.stringLength s)}:${s},"
diff --git a/users/Profpatsch/netstring/default.nix b/users/Profpatsch/netstring/default.nix
index a1d6a1e77f03..333244a0f701 100644
--- a/users/Profpatsch/netstring/default.nix
+++ b/users/Profpatsch/netstring/default.nix
@@ -1,14 +1,5 @@
 { lib, pkgs, depot, ... }:
 let
-  toNetstring = s:
-    "${toString (builtins.stringLength s)}:${s},";
-
-  toNetstringKeyVal = attrs:
-    lib.concatStrings
-      (lib.mapAttrsToList
-        (k: v: toNetstring (toNetstring k + toNetstring v))
-        attrs);
-
   python-netstring = depot.users.Profpatsch.writers.python3Lib {
     name = "netstring";
   } ''
@@ -54,8 +45,6 @@ let
 
 in depot.nix.utils.drvTargets {
   inherit
-    toNetstring
-    toNetstringKeyVal
     python-netstring
     rust-netstring
       ;
diff --git a/users/Profpatsch/netstring/tests/default.nix b/users/Profpatsch/netstring/tests/default.nix
index a9e6c9c688ec..b9fb5835e55a 100644
--- a/users/Profpatsch/netstring/tests/default.nix
+++ b/users/Profpatsch/netstring/tests/default.nix
@@ -3,8 +3,6 @@
 let
 
   inherit (depot.users.Profpatsch.netstring)
-    toNetstring
-    toNetstringKeyVal
     python-netstring
     rust-netstring
     ;
@@ -21,20 +19,20 @@ let
       assert left == right, "{} /= {}".format(str(left), str(right))
 
     assEq(
-      netstring.read_netstring(b"""${toNetstring "hi!"}"""),
+      netstring.read_netstring(b"""${depot.nix.netstring.fromString "hi!"}"""),
       (b"hi!", b"")
     )
 
     assEq(
       netstring.read_netstring_key_val(
-        b"""${toNetstringKeyVal { foo = "42"; }}"""
+        b"""${depot.nix.netstring.attrsToKeyValList { foo = "42"; }}"""
       ),
       (b'foo', b'42', b"")
     )
 
     assEq(
       netstring.read_netstring_key_val_list(
-        b"""${toNetstringKeyVal { foo = "42"; bar = "hi"; }}"""
+        b"""${depot.nix.netstring.attrsToKeyValList { foo = "42"; bar = "hi"; }}"""
       ),
       { b'foo': b'42', b'bar': b'hi' }
     )
@@ -51,11 +49,11 @@ let
     fn main() {
       assert_eq!(
         std::str::from_utf8(&netstring::to_netstring(b"hello")).unwrap(),
-        r##"${toNetstring "hello"}"##
+        r##"${depot.nix.netstring.fromString "hello"}"##
       );
       assert_eq!(
         std::str::from_utf8(&netstring::to_netstring("こんにちは".as_bytes())).unwrap(),
-        r##"${toNetstring "こんにちは"}"##
+        r##"${depot.nix.netstring.fromString "こんにちは"}"##
       );
     }
   '';