about summary refs log tree commit diff
path: root/users/Profpatsch/netencode/netencode-mustache.rs
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-01-02T16·08+0100
committerProfpatsch <mail@profpatsch.de>2021-01-03T16·29+0000
commit27a73171cf97c24c7785787eb7661405334329de (patch)
tree1ef181be663c0eb2b96c7c4320271a928ca46a23 /users/Profpatsch/netencode/netencode-mustache.rs
parentf1c38e25600d4b61b84a5cdba1c7c9a28cc742a7 (diff)
feat(Profpatsch/netencode): add netencode-mustache r/2058
A little executable, combining the netencode and mustache libraries to
make easy templating from the command line possible.

Combined with the nix netencode generators, it’s now trivial to
populate a mustache template with (nearly) arbitrary data.

Yay.

Change-Id: I5b892c38fbc33dd826a26174dd9567f0b72e6322
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2320
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/Profpatsch/netencode/netencode-mustache.rs')
-rw-r--r--users/Profpatsch/netencode/netencode-mustache.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/users/Profpatsch/netencode/netencode-mustache.rs b/users/Profpatsch/netencode/netencode-mustache.rs
new file mode 100644
index 0000000000..796c7a68d4
--- /dev/null
+++ b/users/Profpatsch/netencode/netencode-mustache.rs
@@ -0,0 +1,71 @@
+extern crate netencode;
+extern crate mustache;
+
+use mustache::{Data};
+use netencode::{T};
+use std::collections::HashMap;
+use std::os::unix::ffi::{OsStrExt};
+use std::io::{Read};
+
+fn arglib_netencode(env: Option<&std::ffi::OsStr>) -> Result<T, String> {
+    let env = match env {
+        None => std::ffi::OsStr::from_bytes("ARGLIB_NETENCODE".as_bytes()),
+        Some(a) => a
+    };
+    match std::env::var_os(env) {
+        None => Err(format!("could not read args, envvar {} not set", env.to_string_lossy())),
+        // TODO: good error handling for the different parser errors
+        Some(soup) => match netencode::parse::t_t(soup.as_bytes()) {
+            Ok((remainder, t)) => match remainder.is_empty() {
+                true => Ok(t),
+                false => Err(format!("there was some unparsed bytes remaining: {:?}", remainder))
+            },
+            Err(err) => Err(format!("parsing error: {:?}", err))
+        }
+    }
+}
+
+
+fn netencode_to_mustache_data_dwim(t: T) -> Data {
+    match t {
+        // TODO: good idea?
+        T::Unit => Data::Null,
+        T::N1(b) => Data::Bool(b),
+        T::N3(u) => Data::String(u.to_string()),
+        T::N6(u) => Data::String(u.to_string()),
+        T::N7(u) => Data::String(u.to_string()),
+        T::I3(i) => Data::String(i.to_string()),
+        T::I6(i) => Data::String(i.to_string()),
+        T::I7(i) => Data::String(i.to_string()),
+        T::Text(s) => Data::String(s),
+        T::Binary(b) => unimplemented!(),
+        T::Sum(tag) => unimplemented!(),
+        T::Record(xs) => Data::Map(
+            xs.into_iter()
+                .map(|(key, val)| (key, netencode_to_mustache_data_dwim(*val)))
+                .collect::<HashMap<_,_>>()
+        ),
+        T::List(xs) => Data::Vec(
+            xs.into_iter()
+                .map(|x| netencode_to_mustache_data_dwim(x))
+                .collect::<Vec<_>>()
+        ),
+    }
+}
+
+pub fn from_stdin() -> () {
+    let data = netencode_to_mustache_data_dwim(
+        arglib_netencode(None).unwrap()
+    );
+    let mut stdin = String::new();
+    std::io::stdin().read_to_string(&mut stdin).unwrap();
+    mustache::compile_str(&stdin)
+        .and_then(|templ| templ.render_data(
+            &mut std::io::stdout(),
+            &data
+        )).unwrap()
+}
+
+pub fn main() {
+    from_stdin()
+}