From 9fe1db6193d512f4a61eff180055f14b7d92579d Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Sun, 7 Feb 2021 22:44:50 +0100 Subject: feat(users/Profpatsch/netencode): add `U::to_t()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- users/Profpatsch/netencode/netencode.rs | 39 +++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'users') 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>), @@ -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::>() + ), + U::List(l) => T::List( + l.iter().map(|v| v.to_t()).collect::>() + ), + } + } } #[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 { - // // TODO: implement - // parse::u_into_t(u) - // } - // } + impl<'a> Decoder<'a> for AnyT { + type A = T; + fn dec(&self, u: U<'a>) -> Result { + Ok(u.to_t()) + } + } impl<'a> Decoder<'a> for AnyU { type A = U<'a>; -- cgit 1.4.1