about summary refs log tree commit diff
path: root/users/Profpatsch/netencode/netencode.rs
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2021-02-06T19·31+0100
committerProfpatsch <mail@profpatsch.de>2021-02-06T19·43+0000
commit42974ddd6494097bf8a85a123b8637115977dda4 (patch)
tree00f00965ae4733fed0007f17db6208eb62c5cf99 /users/Profpatsch/netencode/netencode.rs
parent14f9a22f4641ea214af1513bc1f9ef12b1350cbe (diff)
feat(users/Profpatsch/netencode): nest Us in U::List r/2184
Earlier we left the next level of values unencoded, since lists are
just concatenated netencode values. But I noticed that you can’t write
e.g. a `t_to_u` function, because only in the case of lists you need
to allocate memory.

Turns out that if we read the next level of values, everything is
handled the same as in `Record` and things suddenly start working.

We can also throw away some of the strange and ad-hoc parser helpers
we needed before, `skip` and `list_take`, since now those are just
normal `Vec::iter().skip()` and take.

Change-Id: Ibc476e028102944a65c2b64621047086cfc09aa5
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2488
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/Profpatsch/netencode/netencode.rs')
-rw-r--r--users/Profpatsch/netencode/netencode.rs50
1 files changed, 18 insertions, 32 deletions
diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs
index 48a6c576b9..7f8506708d 100644
--- a/users/Profpatsch/netencode/netencode.rs
+++ b/users/Profpatsch/netencode/netencode.rs
@@ -49,7 +49,7 @@ pub enum U<'a> {
     // Tags
     Sum(Tag<&'a str, U<'a>>),
     Record(Vec<(&'a str, U<'a>)>),
-    List(&'a [u8]),
+    List(Vec<U<'a>>),
 }
 
 #[derive(Debug, PartialEq, Eq, Clone)]
@@ -106,8 +106,12 @@ pub fn encode<W: Write>(w: &mut W, u: U) -> std::io::Result<()> {
           write!(w, "}}")
       },
       U::List(l) => {
-          write!(w, "[{}:", l.len())?;
-          w.write(l)?;
+          let mut c = std::io::Cursor::new(vec![]);
+          for u in l {
+              encode(&mut c, u)?;
+          }
+          write!(w, "[{}:", c.get_ref().len())?;
+          w.write(c.get_ref())?;
           write!(w, "]")
       }
   }
@@ -268,29 +272,18 @@ pub mod parse {
     }
 
     fn list_t(s: &[u8]) -> IResult<&[u8], Vec<T>> {
-        map_parser(list_g(), nom::multi::many0(t_t))(s)
-    }
-
-    fn list_g() -> impl Fn(&[u8]) -> IResult<&[u8], &[u8]> {
-        sized('[', ']')
-    }
-
-    fn skip() -> impl Fn(&[u8]) -> IResult<&[u8], ()> {
-        move |s: &[u8]| {
-            let (s, ()) = alt((
-                // TODO: only use the sized parsers here
-                map(text, |_| ()),
-                map(unit_t, |_| ()),
-                map(list_g(), |_| ()),
-                map(t_t, |_| ()),
-                // TODO: add rest of parsers
-            ))(s)?;
-            Ok((s, ()))
-        }
+        list_g(t_t)(s)
     }
 
-    fn list_take<'a>(n: usize) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<U<'a>>> {
-        map_parser(list_g(), nom::multi::many_m_n(n, n, u_u))
+    fn list_g<'a, P, O>(inner: P) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], Vec<O>>
+    where
+        O: Clone,
+        P: Fn(&'a [u8]) -> IResult<&'a [u8], O>
+    {
+        map_parser(
+            sized('[', ']'),
+            nom::multi::many0(inner)
+        )
     }
 
     fn record_t<'a>(s: &'a [u8]) -> IResult<&'a [u8], HashMap<String, T>> {
@@ -328,7 +321,7 @@ pub mod parse {
             map(binary_g(), U::Binary),
             map(unit_t, |()| U::Unit),
             map(tag_g(u_u), |t| U::Sum(t)),
-            map(list_g(), U::List),
+            map(list_g(u_u), U::List),
             map(record_g(u_u), U::Record),
 
             map(bool_t(), |u| U::N1(u)),
@@ -494,13 +487,6 @@ pub mod parse {
                 ]))
             );
             assert_eq!(
-                list_take(2)("[6:u,u,u,]".as_bytes()),
-                Ok(("".as_bytes(), vec![
-                    U::Unit,
-                    U::Unit,
-                ]))
-            );
-            assert_eq!(
                 list_t("[15:u,[7:t3:foo,]u,]".as_bytes()),
                 Ok(("".as_bytes(), vec![
                     T::Unit,