diff options
author | Profpatsch <mail@profpatsch.de> | 2021-02-06T19·31+0100 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2021-02-06T19·43+0000 |
commit | 42974ddd6494097bf8a85a123b8637115977dda4 (patch) | |
tree | 00f00965ae4733fed0007f17db6208eb62c5cf99 /users | |
parent | 14f9a22f4641ea214af1513bc1f9ef12b1350cbe (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')
-rw-r--r-- | users/Profpatsch/netencode/netencode.rs | 50 |
1 files changed, 18 insertions, 32 deletions
diff --git a/users/Profpatsch/netencode/netencode.rs b/users/Profpatsch/netencode/netencode.rs index 48a6c576b9d5..7f8506708de9 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, |