about summary refs log tree commit diff
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-02-07T21·44+0100
committerProfpatsch <mail@profpatsch.de>2021-02-09T01·36+0000
commit9fe1db6193d512f4a61eff180055f14b7d92579d (patch)
treeff183c36861bea01c0c231e8b7ea5c102bba9e28
parent7d9c30ab3d9a9cb72cfcdec0ef060059edca7b1e (diff)
feat(users/Profpatsch/netencode): add `U::to_t()` r/2191
This fell out of us moving the `U::List` to a `Vec`.

I noticed that now we have deep recursion for `U`s, which originally
wasn’t intended; reverting to contain `&[u8]` might be a good
experiment, as long as the lists stay a `Vec<&'a [u8]`, which was the
thing preventing us from parsing lists without allocating memory.

Change-Id: I4900c5dea460fa69a78ce0dbed5708495af5d2e1
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2495
Tested-by: BuildkiteCI
Reviewed-by: Profpatsch <mail@profpatsch.de>
-rw-r--r--users/Profpatsch/netencode/netencode.rs39
1 files changed, 32 insertions, 7 deletions
diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs
index 7099506f6df2..282eaf74bcea 100644
--- a/users/Profpatsch/netencode/netencode.rs
+++ b/users/Profpatsch/netencode/netencode.rs
@@ -80,6 +80,8 @@ pub enum U<'a> {
     Text(&'a str),
     Binary(&'a [u8]),
     // Tags
+    // TODO: the U-recursion we do here means we can’t be breadth-lazy anymore
+    // like we originally planned; maybe we want to go `U<'a>` → `&'a [u8]` again?
     Sum(Tag<&'a str, U<'a>>),
     Record(HashMap<&'a str, U<'a>>),
     List(Vec<U<'a>>),
@@ -91,6 +93,30 @@ impl<'a> U<'a> {
         encode(&mut c, self);
         c.into_inner()
     }
+
+    pub fn to_t(&self) -> T {
+        match self {
+            U::Unit => T::Unit,
+            U::N1(b) => T::N1(*b),
+            U::N3(u) => T::N3(*u),
+            U::N6(u) => T::N6(*u),
+            U::N7(u) => T::N7(*u),
+            U::I3(i) => T::I3(*i),
+            U::I6(i) => T::I6(*i),
+            U::I7(i) => T::I7(*i),
+            U::Text(t) => T::Text((*t).to_owned()),
+            U::Binary(v) => T::Binary((*v).to_owned()),
+            U::Sum(Tag { tag, val }) => T::Sum(
+                Tag { tag: (*tag).to_owned(), val: Box::new(val.to_t()) }
+            ),
+            U::Record(map) => T::Record(
+                map.iter().map(|(k, v)| ((*k).to_owned(), v.to_t())).collect::<HashMap<String, T>>()
+            ),
+            U::List(l) => T::List(
+                l.iter().map(|v| v.to_t()).collect::<Vec<T>>()
+            ),
+        }
+    }
 }
 
 #[derive(Debug, PartialEq, Eq, Clone)]
@@ -609,13 +635,12 @@ pub mod dec {
     #[derive(Clone, Copy)]
     pub struct AnyU;
 
-    // impl Decoder for AnyT {
-    //     type A = T;
-    //     fn dec(u: U) -> Result<Self::A, DecodeError> {
-    //         // TODO: implement
-    //         parse::u_into_t(u)
-    //     }
-    // }
+    impl<'a> Decoder<'a> for AnyT {
+        type A = T;
+        fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> {
+            Ok(u.to_t())
+        }
+    }
 
     impl<'a> Decoder<'a> for AnyU {
         type A = U<'a>;